mirror of
https://github.com/sabnzbd/sabnzbd.git
synced 2025-12-24 08:08:37 -05:00
Compare commits
39 Commits
4.2.0Alpha
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bd39e4c12 | ||
|
|
987032b384 | ||
|
|
d516cbf363 | ||
|
|
824274ac5e | ||
|
|
82b1c784f4 | ||
|
|
232512b860 | ||
|
|
223fa421c7 | ||
|
|
2e5e72bfcf | ||
|
|
9bdb986382 | ||
|
|
901ff30e11 | ||
|
|
5e04599212 | ||
|
|
d3c9b7ead3 | ||
|
|
361770c34b | ||
|
|
5168f3fa97 | ||
|
|
94d307e198 | ||
|
|
eba6236ad2 | ||
|
|
d0128bd989 | ||
|
|
fbd7c0ec36 | ||
|
|
55abac97ea | ||
|
|
740b94170e | ||
|
|
c6a1a09213 | ||
|
|
cd84d52398 | ||
|
|
cdbad1b397 | ||
|
|
67e227008a | ||
|
|
23cf43cac5 | ||
|
|
62a057dbfb | ||
|
|
f2ff9ae557 | ||
|
|
9ed4e46919 | ||
|
|
faa71bae40 | ||
|
|
bbd5d2cd6d | ||
|
|
221e135c07 | ||
|
|
956904c0b3 | ||
|
|
8590481022 | ||
|
|
2171d0139e | ||
|
|
71d6aca9f8 | ||
|
|
0125e279c0 | ||
|
|
b8e46ccf10 | ||
|
|
787fef1c03 | ||
|
|
98b7a6171f |
5
.github/workflows/build_release.yml
vendored
5
.github/workflows/build_release.yml
vendored
@@ -98,10 +98,7 @@ jobs:
|
||||
if: steps.cache-python-download.outputs.cache-hit != 'true'
|
||||
run: curl https://www.python.org/ftp/python/${PYTHON_VERSION}/python-${PYTHON_VERSION}-macos11.pkg -o ~/python.pkg
|
||||
- name: Install Python
|
||||
run: |
|
||||
sudo installer -pkg ~/python.pkg -target /
|
||||
unlink /usr/local/bin/python
|
||||
ln -s /usr/local/bin/python3 /usr/local/bin/python
|
||||
run: sudo installer -pkg ~/python.pkg -target /
|
||||
- name: Cache Python virtualenv
|
||||
uses: syphar/restore-virtualenv@v1.3
|
||||
id: cache-virtualenv
|
||||
|
||||
@@ -1349,7 +1349,6 @@ def main():
|
||||
"server.socket_host": cherryhost,
|
||||
"server.socket_port": cherryport,
|
||||
"server.shutdown_timeout": 0,
|
||||
"log.screen": False,
|
||||
"engine.autoreload.on": False,
|
||||
"tools.encode.on": True,
|
||||
"tools.gzip.on": True,
|
||||
@@ -1361,13 +1360,11 @@ def main():
|
||||
)
|
||||
|
||||
# Do we want CherryPy Logging? Cannot be done via the config
|
||||
cherrypy.log.screen = False
|
||||
cherrypy.log.access_log.propagate = False
|
||||
if cherrypylogging:
|
||||
sabnzbd.WEBLOGFILE = os.path.join(logdir, DEF_LOG_CHERRY)
|
||||
cherrypy.log.screen = True
|
||||
cherrypy.log.access_log.propagate = True
|
||||
cherrypy.log.access_file = str(sabnzbd.WEBLOGFILE)
|
||||
else:
|
||||
cherrypy.log.access_log.propagate = False
|
||||
|
||||
# Force mimetypes (OS might overwrite them)
|
||||
forced_mime_types = {"css": "text/css", "js": "application/javascript"}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# Basic build requirements
|
||||
# Note that not all sub-dependencies are listed, but only ones we know could cause trouble
|
||||
pyinstaller==6.1.0
|
||||
pyinstaller==6.2.0
|
||||
packaging==23.2
|
||||
pyinstaller-hooks-contrib==2023.10
|
||||
altgraph==0.17.4
|
||||
wrapt==1.15.0
|
||||
wrapt==1.16.0
|
||||
setuptools==68.2.2
|
||||
certifi
|
||||
|
||||
# Required on 32bit Windows, exclude it based on Python-version
|
||||
importlib_metadata==6.8.0; python_version < '3.10'
|
||||
importlib_resources==6.1.0; python_version < '3.10'
|
||||
importlib_resources==6.1.1; python_version < '3.10'
|
||||
zipp==3.17.0; python_version < '3.10'
|
||||
|
||||
# orjson does not support 32bit Windows, also exclude based on Python-version
|
||||
orjson==3.9.9; python_version > '3.8'
|
||||
orjson==3.9.10; python_version > '3.8'
|
||||
|
||||
# For the Windows build
|
||||
pefile==2023.2.7; sys_platform == 'win32'
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<!--#set global $pane="Sorting"#-->
|
||||
<!--#set global $help_uri = $confighelpuri + "sorting"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="padTable section explain-sorting">
|
||||
<a class="main-helplink" href="$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
|
||||
$T('explain-sorting')
|
||||
</div>
|
||||
<div class="colmask">
|
||||
<div class="padTable section">
|
||||
<a class="main-helplink" href="$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
|
||||
$T('explain-sorting')
|
||||
</div>
|
||||
<div class="padding alt section">
|
||||
<button type="button" class="btn btn-default addSorter"><span class="glyphicon glyphicon-plus"></span> $T('add-sorter')</button>
|
||||
<label for="advanced-settings-button" class="form-control advanced-button ">
|
||||
@@ -345,7 +344,7 @@
|
||||
</div>
|
||||
|
||||
<!--#if len($slotinfo) == 1 and ("tv" in $categories or "movies" in $categories)#-->
|
||||
<div class="section align-center alt sorting-quick-setup">
|
||||
<div class="section align-center sorting-quick-setup">
|
||||
<h3>$T('sort-quick-add'):</h3>
|
||||
<!--#if "tv" in $categories#-->
|
||||
<form action="save_sorter" method="post" autocomplete="off">
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</div><!-- /col2 -->
|
||||
<div class="col1">
|
||||
<fieldset>
|
||||
<div class="field-pair">
|
||||
<div class="field-pair advanced-settings">
|
||||
<label class="config" for="pre_script">$T('opt-pre_script')</label>
|
||||
<select name="pre_script" id="pre_script">
|
||||
<!--#for $sc in $scripts#-->
|
||||
@@ -54,6 +54,19 @@
|
||||
</select>
|
||||
<span class="desc">$T('explain-pre_script')</span>
|
||||
</div>
|
||||
<div class="field-pair advanced-settings">
|
||||
<label class="config" for="end_queue_script">$T('opt-end_queue_script')</label>
|
||||
<select name="end_queue_script" id="end_queue_script">
|
||||
<!--#for $sc in $scripts#-->
|
||||
<!--#if $sc.lower() == $end_queue_script.lower()#-->
|
||||
<option value="$sc" selected="selected">$Tspec($sc)</option>
|
||||
<!--#else#-->
|
||||
<option value="$sc">$Tspec($sc)</option>
|
||||
<!--#end if#-->
|
||||
<!--#end for#-->
|
||||
</select>
|
||||
<span class="desc">$T('explain-end_queue_script')</span>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label class="config" for="propagation_delay">$T('opt-propagation_delay')</label>
|
||||
<input type="number" name="propagation_delay" id="propagation_delay" value="$propagation_delay" /> <i>$T('minutes')</i>
|
||||
|
||||
@@ -107,7 +107,6 @@ select.form-control,
|
||||
.navbar-default,
|
||||
.search-box input,
|
||||
.select,
|
||||
.Sorting .explain-sorting,
|
||||
.table-striped>tbody>tr:nth-child(even),
|
||||
.table>tbody>tr:nth-child(even),
|
||||
.tab-pane tr:nth-child(odd),
|
||||
|
||||
@@ -359,10 +359,6 @@ tr.separator {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.Sorting .explain-sorting {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
.Sorting .explain-pattern {
|
||||
border: none;
|
||||
width: 100%;
|
||||
|
||||
@@ -102,26 +102,15 @@
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header"><span class="glyphicon glyphicon-off"></span> $T('Glitter-onFinish'):</li>
|
||||
<li>
|
||||
<!-- ko if: queue.scriptsListLoaded -->
|
||||
<select data-bind="value: finishaction, event: { change: setOnQueueFinish }" class="form-control">
|
||||
<option value=""></option>
|
||||
<optgroup label="$T('eoq-actions')">
|
||||
<option value="shutdown_program">$T('shutdownSab')</option>
|
||||
<!--#if $power_options#-->
|
||||
<option value="shutdown_pc">$T('shutdownPc')</option>
|
||||
<option value="standby_pc">$T('standbyPc')</option>
|
||||
<option value="hibernate_pc">$T('hibernatePc')</option>
|
||||
<!--#end if#-->
|
||||
</optgroup>
|
||||
<optgroup label="$T('eoq-scripts')" data-bind="visible: queue.scriptsList().length > 1">
|
||||
<!-- ko foreach: queue.scriptsList -->
|
||||
<!-- ko if: \$data.scriptValue != 'None' -->
|
||||
<option data-bind="text: \$data.scriptText, attr: { value: 'script_'+\$data.scriptValue } " ></option>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
</optgroup>
|
||||
<option value="shutdown_program">$T('shutdownSab')</option>
|
||||
<!--#if $power_options#-->
|
||||
<option value="shutdown_pc">$T('shutdownPc')</option>
|
||||
<option value="standby_pc">$T('standbyPc')</option>
|
||||
<option value="hibernate_pc">$T('hibernatePc')</option>
|
||||
<!--#end if#-->
|
||||
</select>
|
||||
<!-- /ko -->
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
glitterTranslate.fetch = "$T('Glitter-fetch')";
|
||||
glitterTranslate.checking = "$T('post-Checking')";
|
||||
glitterTranslate.misingArt = "$T('missingArt')";
|
||||
glitterTranslate.fetchingURL = "$T('Glitter-addFromURL')"
|
||||
glitterTranslate.chooseFile = "$T('Glitter-chooseFile')";
|
||||
glitterTranslate.orphanedJobsMsg = "$T('explain-orphans')";
|
||||
glitterTranslate.useCache = "$T('explain-cache_limitstr').replace("64M", "256M").replace("128M", "512M")";
|
||||
|
||||
@@ -1110,11 +1110,7 @@ function ViewModel() {
|
||||
if(script === 'None') return { scriptValue: 'None', scriptText: glitterTranslate.noneText };
|
||||
return { scriptValue: script, scriptText: script };
|
||||
}))
|
||||
self.queue.scriptsListLoaded(true)
|
||||
})
|
||||
} else {
|
||||
// We can already continue
|
||||
self.queue.scriptsListLoaded(true)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ function QueueListModel(parent) {
|
||||
self.multiEditItems = ko.observableArray([]);
|
||||
self.categoriesList = ko.observableArray([]);
|
||||
self.scriptsList = ko.observableArray([]);
|
||||
self.scriptsListLoaded = ko.observable(false);
|
||||
self.searchTerm = ko.observable('').extend({ rateLimit: { timeout: 400, method: "notifyWhenChangesStop" } });
|
||||
self.paginationLimit = ko.observable(20).extend({ persist: 'queuePaginationLimit' });
|
||||
self.pagination = new paginationModel(self);
|
||||
@@ -507,6 +506,9 @@ function QueueModel(parent, data) {
|
||||
|
||||
// MB's
|
||||
self.progressText = ko.pureComputed(function() {
|
||||
if(self.isGrabbing()) {
|
||||
return glitterTranslate.fetchingURL
|
||||
}
|
||||
return (self.totalMB() - self.remainingMB()).toFixed(0) + " MB / " + (self.totalMB() * 1).toFixed(0) + " MB";
|
||||
})
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: ION, 2020\n"
|
||||
"Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\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://app.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
@@ -241,7 +241,7 @@ msgstr ""
|
||||
msgid "Server address required"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr ""
|
||||
|
||||
@@ -1082,6 +1082,18 @@ msgstr ""
|
||||
msgid "NZB added to queue"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1096,26 +1108,6 @@ msgstr ""
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1134,6 +1126,10 @@ msgstr ""
|
||||
msgid "DUPLICATE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr ""
|
||||
@@ -1179,6 +1175,10 @@ msgstr ""
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2133,11 +2133,6 @@ msgstr ""
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3008,6 +3003,14 @@ msgstr ""
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr ""
|
||||
@@ -4462,10 +4465,6 @@ msgstr ""
|
||||
msgid "Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr ""
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
@@ -266,7 +266,7 @@ msgstr "%s není validní emailová adresa"
|
||||
msgid "Server address required"
|
||||
msgstr "Adresa serveru je vyžadována"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr ""
|
||||
|
||||
@@ -291,7 +291,7 @@ msgstr "UNC cesta \"%s\" zde není povolena"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Fronta nené prázdná, nelze změnit složku."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1149,6 +1149,18 @@ msgstr "Nelze nahrát %s, detekován porušený soubor"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB přidáno do fronty"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignoruji duplikátní NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Nezdařilo se duplikovat NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Duplikátní NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1163,26 +1175,6 @@ msgstr "Prázdný NZB soubor %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignoruji duplikátní NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Nezdařilo se duplikovat NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Duplikátní NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pozastavuji duplikátní NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1201,6 +1193,10 @@ msgstr "Chyba při importu %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLIKÁT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ŠIFROVANÉ"
|
||||
@@ -1246,6 +1242,10 @@ msgstr ""
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pozastavuji duplikátní NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2208,11 +2208,6 @@ msgstr "Jméno"
|
||||
msgid "Retry"
|
||||
msgstr "Opakovat"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Akce"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3163,6 +3158,14 @@ msgstr ""
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr ""
|
||||
@@ -4671,10 +4674,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr ""
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
@@ -266,7 +266,7 @@ msgstr "%s er ikke en godkendt e-mail adresse"
|
||||
msgid "Server address required"
|
||||
msgstr "Kræver serveradresse"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Ugyldig server adresse."
|
||||
|
||||
@@ -291,7 +291,7 @@ msgstr "UNC søgning \"%s\" er ikke tilladt her"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Køen er ikke tom, kan ikke skifte mappe."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1153,6 +1153,18 @@ msgstr "Downloadnings fejl %s, ødelagt fil fundet"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB tilføjet i køen"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerer identiske NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Fejler dublet NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dublet NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1167,26 +1179,6 @@ msgstr "Tom NZB fil %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "Før-kø script job markeret som mislykkedet"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerer identiske NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Fejler dublet NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dublet NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pause duplikeret NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1205,6 +1197,10 @@ msgstr "Det lykkedes ikke at importere %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLIKERE"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "KRYPTEREDE"
|
||||
@@ -1250,6 +1246,10 @@ msgstr "%s artikler manglede"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artikler havde ikke-matchende dubletter"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pause duplikeret NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2240,11 +2240,6 @@ msgstr "Navn"
|
||||
msgid "Retry"
|
||||
msgstr "Forsøg igen"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Handlinger"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3239,6 +3234,14 @@ msgstr "Før kø bruger script"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Brugt før, en NZB kommer ind i køen."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Ekstra PAR2 parameter"
|
||||
@@ -4783,10 +4786,6 @@ msgstr ""
|
||||
"Ukendt SSL protokol: Prøv at deaktivere SSL eller forbinder på en anden "
|
||||
"port."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Server afslut under login-sekvens."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Serveren kræver brugernavn og adgangskode."
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
@@ -285,7 +285,7 @@ msgstr "%s ist keine gültige E-Mail-Adresse"
|
||||
msgid "Server address required"
|
||||
msgstr "Server-Adresse wird benötigt"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Ungültige Server-Adresse."
|
||||
|
||||
@@ -313,6 +313,7 @@ msgstr "UNC-Pfad \"%s\" ist hier nicht erlaubt"
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
"Ordner kann nicht geändert werden, da die Warteschlange nicht leer ist."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1202,6 +1203,18 @@ msgstr "Fehler beim Laden von %s. Beschädigte Datei gefunden."
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB zur Warteschlange hinzugefügt"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Doppelte NZB \"%s\" wird ignoriert"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "kopieren der NZB \"%s\" fehlgeschlagen"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Doppelte NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1218,26 +1231,6 @@ msgstr ""
|
||||
"Das Vorwarteschlangen (pre-queue) Skript hat die Downloadaufgabe als "
|
||||
"gescheitert markiert"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Doppelte NZB \"%s\" wird ignoriert"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "kopieren der NZB \"%s\" fehlgeschlagen"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Doppelte NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Doppelt vorhandene NZB \"%s\" angehalten"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1256,6 +1249,10 @@ msgstr "Fehler beim Importieren von %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLIKAT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "VERSCHLÜSSELT"
|
||||
@@ -1302,6 +1299,10 @@ msgstr "%s Artikel fehlten"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s Artikel hatten nicht übereinstimmende Duplikate"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Doppelt vorhandene NZB \"%s\" angehalten"
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2304,11 +2305,6 @@ msgstr "Name"
|
||||
msgid "Retry"
|
||||
msgstr "Erneut versuchen"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Aktionen"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3362,6 +3358,14 @@ msgid "Used before an NZB enters the queue."
|
||||
msgstr ""
|
||||
"Wird verwendet, bevor eine NZB-Datei zur Warteschlange hinzugefügt wird."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Zusätzliche PAR2-Parameter"
|
||||
@@ -4956,10 +4960,6 @@ msgstr ""
|
||||
"Unbekanntes SSL-Protokoll: SSL deaktivieren oder alternativen Port "
|
||||
"versuchen."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Sever beendet beim Anmeldeverlauf."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Server benötigt ein Benutzername und ein Passwort."
|
||||
|
||||
@@ -124,4 +124,7 @@ msgid "0 is highest priority, 100 is the lowest priority"
|
||||
msgstr "0 is highest priority, 99 is the lowest priority"
|
||||
|
||||
msgid "Filter out sample files (e.g. video samples)."
|
||||
msgstr "Filter out sample files (e.g. video samples/proofs)."
|
||||
msgstr "Filter out sample files (e.g. video samples/proofs)."
|
||||
|
||||
msgid "Pre-queue user script"
|
||||
msgstr "Pre-queue script"
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Spanish (https://app.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
@@ -281,7 +281,7 @@ msgstr "%s no es una dirección de correo electrónico válida."
|
||||
msgid "Server address required"
|
||||
msgstr "Se necesita la dirección del servidor"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Dirección del servidor no válida."
|
||||
|
||||
@@ -306,7 +306,7 @@ msgstr "Ruta de acceso UNC \"%s\" no permitido aqui"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Cola no esta vacía, no se puede cambiar el directorio"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1196,6 +1196,18 @@ msgstr "Error al cargar %s, archivo corrupto"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB añadido a la cola"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorando NZB Duplicado \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Fallo al duplicar NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Duplicar NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1212,26 +1224,6 @@ msgstr ""
|
||||
"La secuencia de comandos de la cola preestablecida ha marcado la tarea como "
|
||||
"fallida"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorando NZB Duplicado \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Fallo al duplicar NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Duplicar NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausando NZB duplicados \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1250,6 +1242,10 @@ msgstr "Error importando %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLICADO"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ENCRIPTADO"
|
||||
@@ -1295,6 +1291,10 @@ msgstr "%s artículos no encontrados"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artículos contenían duplicados inconexos"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausando NZB duplicados \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2296,11 +2296,6 @@ msgstr "Nombre"
|
||||
msgid "Retry"
|
||||
msgstr "Reintentar"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Acciones"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3323,6 +3318,14 @@ msgstr "Script de usuario Pre-cola"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Se usa precediendo a la entrada de un NZB en la cola del sistema."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Parámetros PAR2 extra"
|
||||
@@ -4891,10 +4894,6 @@ msgstr ""
|
||||
"Protocolo SSL desconocido: intente desabilitar el SSL o conectarse a un "
|
||||
"puerto diferente."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "El servidor se ha cerrado durante el login"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "El servidor necesita usuario y contraseña."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
@@ -264,7 +264,7 @@ msgstr "%s ei ole kelvollinen sähköpostiosoite"
|
||||
msgid "Server address required"
|
||||
msgstr "Palvelimen osoite vaaditaan"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Virheellinen palvelimen osoite."
|
||||
|
||||
@@ -289,7 +289,7 @@ msgstr "TUNT polku \"%s\" ei ole sallittu"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Jono ei ole tyhjä, kansiota ei voida vaihtaa."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1147,6 +1147,18 @@ msgstr "Virhe ladattaessa %s, korruptoitunut tiedosto havaittu"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB lisätty jonoon"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ohitetaan kaksoiskappale NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1161,26 +1173,6 @@ msgstr "Tyhjä NZB tiedosto %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ohitetaan kaksoiskappale NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Keskeytetään kaksoiskappale NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1199,6 +1191,10 @@ msgstr "Virhe tuotaessa %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "KAKSOISKAPPALE"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "SALATTU"
|
||||
@@ -1244,6 +1240,10 @@ msgstr "%s artikkelia puuttui"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artikkelissa oli ei-vastaavia kaksoiskappaleita"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Keskeytetään kaksoiskappale NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2234,11 +2234,6 @@ msgstr "Nimi"
|
||||
msgid "Retry"
|
||||
msgstr "Yritä uudelleen"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Toiminnot"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3242,6 +3237,14 @@ msgstr "Esijonon käyttäjän skripti"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Käytetään ennen NZB lisäämistä jonoon."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Ylimääräiset PAR2 parametrit"
|
||||
@@ -4788,10 +4791,6 @@ msgid ""
|
||||
msgstr ""
|
||||
"Tuntematon SSL protokolla: Kokeile ottaa SSL käytöstä tai vaihda porttia."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Palvelin lopetettiin kesken kirjautumisen"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Palvelin vaatii käyttäjänimen ja salasanan."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Fred L <88com88@gmail.com>, 2023\n"
|
||||
"Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
@@ -283,7 +283,7 @@ msgstr "%s n'est pas une adresse email valide"
|
||||
msgid "Server address required"
|
||||
msgstr "Adresse du serveur requise"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Adresse du serveur erronée"
|
||||
|
||||
@@ -1203,6 +1203,18 @@ msgstr "Erreur lors du chargement de %s, fichier corrompu détecté"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB ajouté à la file d'attente"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Doublon NZB ignoré \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Échec de duplication du NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dupliquer NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1217,26 +1229,6 @@ msgstr "Fichier NZB %s vide"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "Le script de pré-file d'attente a marqué la tâche comme échouée"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Doublon NZB ignoré \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Échec de duplication du NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dupliquer NZB"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Mise en pause du doublon NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1255,6 +1247,10 @@ msgstr "Erreur lors de l'importation de %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DOUBLON"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "CHIFFRÉ"
|
||||
@@ -1300,6 +1296,10 @@ msgstr "%s articles manquants"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s articles avec doublons sans correspondance"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Mise en pause du doublon NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2303,11 +2303,6 @@ msgstr "Nom"
|
||||
msgid "Retry"
|
||||
msgstr "Réessayer"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Actions"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3363,6 +3358,14 @@ msgstr "Script utilisateur de pré-file d'attente"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Utilisé avant qu'un NZB n'entre dans la file d'attente."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr "Script de fin de file d'attente"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr "Exécuté après la fin du téléchargement de la file d'attente."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Paramètres PAR2 supplémentaires"
|
||||
@@ -4964,10 +4967,6 @@ msgstr ""
|
||||
"Protocole SSL inconnu: essayez de désactiver SSL ou de vous connecter sur un"
|
||||
" autre port."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Le serveur a interrompu l'ouverture de session."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Le serveur requiert un identifiant et un mot de passe."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n"
|
||||
@@ -262,7 +262,7 @@ msgstr "%s אינה כתובת דוא״ל תקפה"
|
||||
msgid "Server address required"
|
||||
msgstr "כתובת שרת דרושה"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "כתובת שרת בלתי תקפה."
|
||||
|
||||
@@ -288,7 +288,7 @@ msgstr "נתיב UNC \"%s\" אינו מותר כאן"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "התור אינו ריק, לא ניתן לשנות תיקייה."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1150,6 +1150,18 @@ msgstr "שגיאה בטעינת %s, קובץ פגום התגלה"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB התווסף לתור"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "מתעלם מן NZB כפול \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "מכשיל NZB כפול \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "NZB כפול"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1164,26 +1176,6 @@ msgstr "קובץ NZB ריק %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "תסריט קדם־תור סומן כנכשל"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "מתעלם מן NZB כפול \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "מכשיל NZB כפול \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "NZB כפול"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "משהה NZB כפול \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1202,6 +1194,10 @@ msgstr "שגיאה ביבוא %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "כפול"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "מוצפן"
|
||||
@@ -1247,6 +1243,10 @@ msgstr "%s מאמרים היו חסרים"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "אל %s מאמרים יש כפילויות בלתי תואמות"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "משהה NZB כפול \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2241,11 +2241,6 @@ msgstr "שם"
|
||||
msgid "Retry"
|
||||
msgstr "נסה שוב"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "פעולות"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3248,6 +3243,14 @@ msgstr "תסריט משתמש של קדם־תור"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "בשימוש לפני ש־NZB נכנס לתור."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "פרמטרי PAR2 נוספים"
|
||||
@@ -4792,10 +4795,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr "פרוטוקול SSL בלתי ידוע: נסה להשבית SSL או להתחבר על פתחה שונה."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "שרת יצא במהלך רצף כניסות."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr ".השרת דורש שם משתמש וסיסמה"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Norwegian Bokmål (https://app.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
@@ -260,7 +260,7 @@ msgstr "%s er ikke en godkjent e-post-adresse"
|
||||
msgid "Server address required"
|
||||
msgstr "Krever server-adresse"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Ugyldig server-adresse."
|
||||
|
||||
@@ -285,7 +285,7 @@ msgstr "UNC-sti \"%s\" er ikke tillatt her"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Køen er ikke tom, kan ikke bytte mappe."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1143,6 +1143,18 @@ msgstr "Lastingsfeil %s, feilaktig fil oppdaget"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB er lagt til i køen"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerer duplikatfil \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1157,26 +1169,6 @@ msgstr "Tom NZB-fil %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerer duplikatfil \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Stanser duplikatfil \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1195,6 +1187,10 @@ msgstr "Kunne ikke importere %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLIKAT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "KRYPTERT"
|
||||
@@ -1240,6 +1236,10 @@ msgstr "%s artikler manglet"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artikler hadde ulike duplikater"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Stanser duplikatfil \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2230,11 +2230,6 @@ msgstr "Navn"
|
||||
msgid "Retry"
|
||||
msgstr "Prøv igjen"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Hendelser"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3223,6 +3218,14 @@ msgstr "Før-kø bruker skript"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Brukes før en NZB blir lagt til kø"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Ekstra PAR2 parametere"
|
||||
@@ -4759,10 +4762,6 @@ msgstr ""
|
||||
"Ukjent SSL-protokoll: Prøv å deaktivere SSL eller koble til på en annen "
|
||||
"port."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Server avbrøt undet innloggingssekvens"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Server krever brukernavn og passord."
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
@@ -276,7 +276,7 @@ msgstr "%s is geen geldig e-mailadres"
|
||||
msgid "Server address required"
|
||||
msgstr "Serveradres verplicht"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Ongeldige servernaam"
|
||||
|
||||
@@ -303,7 +303,7 @@ msgstr "UNC-pad '%s' hier niet toegestaan."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Wachtrij is niet leeg, andere map kiezen niet mogelijk."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1189,6 +1189,18 @@ msgstr "Fout bij inladen van %s, corrupt bestand gevonden"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "Download aan wachtrij toegevoegd"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Dubbele download \"%s\" overgeslagen"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Download '%s' geweigerd omdat het een dubbele is"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dubbele download"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1203,26 +1215,6 @@ msgstr "NZB-bestand %s is leeg"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "Wachtrij filter script heeft de download afgekeurd"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Dubbele download \"%s\" overgeslagen"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Download '%s' geweigerd omdat het een dubbele is"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "Dubbele download"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Dubbele download \"%s\" gepauzeerd"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1241,6 +1233,10 @@ msgstr "Fout bij importeren van %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUBBEL"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "VERSLEUTELD"
|
||||
@@ -1286,6 +1282,10 @@ msgstr "%s artikelen ontbreken"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artikelen hadden afwijkende duplicaten"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Dubbele download \"%s\" gepauzeerd"
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2281,11 +2281,6 @@ msgstr "Naam"
|
||||
msgid "Retry"
|
||||
msgstr "Opnieuw"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Acties"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3320,6 +3315,14 @@ msgstr "Wachtrij-filter script"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Word uitgevoerd vóór een download aan de wachtrij word toegevoegd"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Extra PAR2 parameters"
|
||||
@@ -4896,10 +4899,6 @@ msgid ""
|
||||
msgstr ""
|
||||
"Onbekend SSL protocol: probeer het zonder SSL of probeer een andere poort."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "De server stopte tijdens de login"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Server heeft een gebruikersnaam en een wachtwoord nodig."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
@@ -256,7 +256,7 @@ msgstr "%s nie jest prawidłowym adresem email"
|
||||
msgid "Server address required"
|
||||
msgstr "Wymagane jest podanie adresu serwera"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Nieprawidłowy adres serwera."
|
||||
|
||||
@@ -281,7 +281,7 @@ msgstr "Ścieżka UNC \"%s\" niedozwolona"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Kolejka nie jest pusta, nie można zmienić katalogu."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1145,6 +1145,18 @@ msgstr "Błąd ładowania %s, wykryto uszkodzony plik"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB dodany do kolejki"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignoruję zduplikowany NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1159,26 +1171,6 @@ msgstr "Pusty plik NZB %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignoruję zduplikowany NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Wstrzymuję zduplikowany NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1197,6 +1189,10 @@ msgstr "Błąd importu %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLIKAT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ZASZYFROWANY"
|
||||
@@ -1242,6 +1238,10 @@ msgstr "Brakowało %s artykułów"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artykułów posiadało niepasujące duplikaty"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Wstrzymuję zduplikowany NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2236,11 +2236,6 @@ msgstr "Nazwa"
|
||||
msgid "Retry"
|
||||
msgstr "Ponów"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Działania"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3231,6 +3226,14 @@ msgstr "Skrypt użytkownika przed zakolejkowaniem"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Uruchamiany zanim plik NZB zostanie umieszczony w kolejce"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Dodatkowe parametry PAR2"
|
||||
@@ -4768,10 +4771,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Serwer przerwał połączenie w trakcie logowania."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Serwer wymaga podania nazwy użytkownika i hasła."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
@@ -260,7 +260,7 @@ msgstr "%s não é um endereço de e-mail válido"
|
||||
msgid "Server address required"
|
||||
msgstr "Endereço do servidor necessário"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Endereço do servidor inválido."
|
||||
|
||||
@@ -285,7 +285,7 @@ msgstr "O caminho UNC \"%s\" não é permitido aqui"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "A fila não está vazia. Não será possível mudar de pasta."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1146,6 +1146,18 @@ msgstr "Erro ao carregar %s. Arquivo corrompido detectado"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB adicionado à fila"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorando NZB duplicado \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1160,26 +1172,6 @@ msgstr "Arquivo NZB %s vazio"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorando NZB duplicado \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausando NZB duplicado \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1198,6 +1190,10 @@ msgstr "Erro ao importar %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLICADO"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "CRIPTOGRAFADO"
|
||||
@@ -1243,6 +1239,10 @@ msgstr "%s artigos estavam faltando"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artigos tinham duplicatas não-correspondentes"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausando NZB duplicado \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2239,11 +2239,6 @@ msgstr "Nome"
|
||||
msgid "Retry"
|
||||
msgstr "Repetir"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Ações"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3233,6 +3228,14 @@ msgstr "Script de usuário de pré-fila"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Utilizado antes de um NZB entrar na fila."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Parâmetros Extras PAR2"
|
||||
@@ -4768,10 +4771,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Servidor parou durante a sequência de login."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Servidor requer usuário e senha."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
@@ -271,7 +271,7 @@ msgstr "%s nu este o adresă email validă"
|
||||
msgid "Server address required"
|
||||
msgstr "Adresă server necesară"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Adresă server invalidă"
|
||||
|
||||
@@ -296,7 +296,7 @@ msgstr "cale UNC \"%s\" nu este premisă aici"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Coada nu este goală, nu pot schimba dosar."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1171,6 +1171,18 @@ msgstr "Eroare încărcare %s, fişier corupt detectat"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB adăugat în coadă"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorăm duplicat NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Eșuare duplicat NZB „%s”"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "NZB duplicat"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1185,26 +1197,6 @@ msgstr "Fişier NZB gol %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "Scriptul pre-coadă a marcat sarcina ca nereușită"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorăm duplicat NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "Eșuare duplicat NZB „%s”"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "NZB duplicat"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Întrerupem duplicat NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1223,6 +1215,10 @@ msgstr "Eroare importare %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUPLICAT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ENCRIPTAT"
|
||||
@@ -1268,6 +1264,10 @@ msgstr "%s articolele au fost lipsă"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s articolele au avut duplicate diferite"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Întrerupem duplicat NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2266,11 +2266,6 @@ msgstr "Nume"
|
||||
msgid "Retry"
|
||||
msgstr "Reîncearcă"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Acțiuni"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3260,6 +3255,14 @@ msgstr "Script utilizator Pre-Coadă"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Folosit înainte ca un NZB să intre în coadă."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Parametri Extra PAR2"
|
||||
@@ -4801,10 +4804,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Serverul a renunţat în timpul logării."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Serverul necesită nume utilizator şi parolă"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
@@ -260,7 +260,7 @@ msgstr "%s не является допустимым адресом элект
|
||||
msgid "Server address required"
|
||||
msgstr "Требуется адрес сервера"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Недопустимый адрес сервера."
|
||||
|
||||
@@ -285,7 +285,7 @@ msgstr "UNC-путь «%s» здесь не допускается"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Очередь не пустая, папку нельзя изменить."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1144,6 +1144,18 @@ msgstr "Ошибка загрузки %s: обнаружен повреждён
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB-файл добавлен в очередь"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Пропущен повторяющийся NZB-файл «%s»"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1158,26 +1170,6 @@ msgstr "Пустой NZB-файл %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Пропущен повторяющийся NZB-файл «%s»"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Приостановлен повторяющийся NZB-файл «%s»"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1196,6 +1188,10 @@ msgstr "Ошибка импорта %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "ПОВТОР"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ЗАШИФРОВАН"
|
||||
@@ -1241,6 +1237,10 @@ msgstr "%s статей отсутствует"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s статей содержат несовпадающие повторы"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Приостановлен повторяющийся NZB-файл «%s»"
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2233,11 +2233,6 @@ msgstr "Название"
|
||||
msgid "Retry"
|
||||
msgstr "Повторить"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Действия"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3225,6 +3220,14 @@ msgstr "Пользовательский сценарий до помещени
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Используется до того, как NZB помещается в очередь."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Дополнительные параметры PAR2"
|
||||
@@ -4764,10 +4767,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Во время входа на сервер был выполнен выход."
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Для сервера требуется имя пользователя и пароль."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
@@ -258,7 +258,7 @@ msgstr "%s nije ispravna email adresa"
|
||||
msgid "Server address required"
|
||||
msgstr "Потребна је адреса сервера"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Погрешна адреса сервера."
|
||||
|
||||
@@ -283,7 +283,7 @@ msgstr "UNC путања \"%s\" није дозвољена"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Pед није празан, фасцикла се не може променити."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1140,6 +1140,18 @@ msgstr "Грешка учитавање %s, покварена датотека
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB додат у ред"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Игнорисање дуплог NZB-а \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1154,26 +1166,6 @@ msgstr "Празан NZB %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Игнорисање дуплог NZB-а \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Паузирам због дуплог NZB-а \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1192,6 +1184,10 @@ msgstr "Грешка увоза %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "ДУПЛИКАТ"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "ШИФРИРАНО"
|
||||
@@ -1237,6 +1233,10 @@ msgstr "%s артикла недостају"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s артикла нису дупликате"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Паузирам због дуплог NZB-а \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2227,11 +2227,6 @@ msgstr "Име"
|
||||
msgid "Retry"
|
||||
msgstr "Покушај опет"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Акције"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3214,6 +3209,14 @@ msgstr "Кориснички скрипт пре-реда"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Коришћено пре него што NZB уђе у ред."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Додатни параметри PAR2"
|
||||
@@ -4743,10 +4746,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Сервер се затворио при пријављивање"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Серверу су потребни име и лозинка."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
@@ -258,7 +258,7 @@ msgstr "%s är inte en godkänd e-mail adress"
|
||||
msgid "Server address required"
|
||||
msgstr "Kräver serveradress"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "Ogiltig serveradress"
|
||||
|
||||
@@ -283,7 +283,7 @@ msgstr "UNC sökväg \"%s\" är inte tillåten här"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "Kön är inte tom, kan inte byta mapp."
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1144,6 +1144,18 @@ msgstr "Laddningsfel %s, felaktig fil detekterad"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB tillagd i kön"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerar dubblett för NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1158,26 +1170,6 @@ msgstr "NZB filen %s är tom"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "Ignorerar dubblett för NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausar dubblett för NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1196,6 +1188,10 @@ msgstr "Det gick inte att importera %s"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "DUBLETT"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "KRYPTERAT"
|
||||
@@ -1241,6 +1237,10 @@ msgstr "%s artiklar saknades"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s artiklar hade icke-matchande dubletter"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "Pausar dubblett för NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2233,11 +2233,6 @@ msgstr "Namn"
|
||||
msgid "Retry"
|
||||
msgstr "Försök igen"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "Åtgärder"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3224,6 +3219,14 @@ msgstr "Kö-specifika användarskript"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "Används innan en NZB tas in i kön."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "Extra PAR2 parametrar"
|
||||
@@ -4757,10 +4760,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "Servern avslutades under inloggning"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "Servern kräver användarnamn och lösenord."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2023\n"
|
||||
"Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
@@ -256,7 +256,7 @@ msgstr "%s 不是有效的电子邮箱地址"
|
||||
msgid "Server address required"
|
||||
msgstr "服务器地址必填"
|
||||
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py, sabnzbd/utils/servertests.py
|
||||
#: sabnzbd/cfg.py, sabnzbd/newswrapper.py
|
||||
msgid "Invalid server address."
|
||||
msgstr "服务器地址无效。"
|
||||
|
||||
@@ -281,7 +281,7 @@ msgstr "此处不允许使用 UNC 路径 \"%s\""
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "Queue not empty, cannot change folder."
|
||||
msgstr ""
|
||||
msgstr "队列非空,无法变更文件夹。"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid ""
|
||||
@@ -1133,6 +1133,18 @@ msgstr "无法加载 %s,侦测到损坏文件"
|
||||
msgid "NZB added to queue"
|
||||
msgstr "NZB 已添加到队列"
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "正在忽略重复 NZB \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "失败于重复的 NZB 文件 \"%s\""
|
||||
|
||||
#: sabnzbd/nzbqueue.py, sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "重复的 NZB 文件"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (error: %s)"
|
||||
@@ -1147,26 +1159,6 @@ msgstr "空 NZB 文件 %s"
|
||||
msgid "Pre-queue script marked job as failed"
|
||||
msgstr "预队列脚本将任务标记为失败的"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Ignoring duplicate NZB \"%s\""
|
||||
msgstr "正在忽略重复 NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Failing duplicate NZB \"%s\""
|
||||
msgstr "失败于重复的 NZB 文件 \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Duplicate NZB"
|
||||
msgstr "重复的 NZB 文件"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "正在暂停重复 NZB \"%s\""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Unwanted Extension in file %s (%s)"
|
||||
@@ -1185,6 +1177,10 @@ msgstr "导入 %s 出错"
|
||||
msgid "DUPLICATE"
|
||||
msgstr "*重复*"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ALTERNATIVE"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "ENCRYPTED"
|
||||
msgstr "*加密*"
|
||||
@@ -1230,6 +1226,10 @@ msgstr "%s 篇文章缺失"
|
||||
msgid "%s articles had non-matching duplicates"
|
||||
msgstr "%s 篇文章存在未匹配的重复"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Pausing duplicate NZB \"%s\""
|
||||
msgstr "正在暂停重复 NZB \"%s\""
|
||||
|
||||
#. Footer: indicator of warnings
|
||||
#: sabnzbd/osxmenu.py, sabnzbd/skintext.py
|
||||
msgid "Warnings"
|
||||
@@ -2220,11 +2220,6 @@ msgstr "名称"
|
||||
msgid "Retry"
|
||||
msgstr "重试"
|
||||
|
||||
#. Queue end-of-queue selection box
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Actions"
|
||||
msgstr "操作"
|
||||
|
||||
#. Queue page table, script selection menu
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Scripts"
|
||||
@@ -3173,6 +3168,14 @@ msgstr "加入队列前执行的用户脚本"
|
||||
msgid "Used before an NZB enters the queue."
|
||||
msgstr "用于在 NZB 进入队列前执行。"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "On queue finish script"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Executed after the queue finishes downloading."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Extra PAR2 Parameters"
|
||||
msgstr "额外的 PAR2 参数"
|
||||
@@ -4691,10 +4694,6 @@ msgid ""
|
||||
"Unknown SSL protocol: Try disabling SSL or connecting on a different port."
|
||||
msgstr "未知的 SSL 协议:尝试禁用 SSL 或者连接不同的端口。"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server quit during login sequence."
|
||||
msgstr "登录过程中服务器退出。"
|
||||
|
||||
#: sabnzbd/utils/servertests.py
|
||||
msgid "Server requires username and password."
|
||||
msgstr "服务器需要用户名与密码。"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Pavel C <quoing_transifex@mess.cz>, 2022\n"
|
||||
"Language-Team: Czech (https://app.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Danish (https://app.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: reloxx13 <reloxx@interia.pl>, 2022\n"
|
||||
"Language-Team: German (https://app.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\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://app.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Fred L <88com88@gmail.com>, 2021\n"
|
||||
"Language-Team: French (https://app.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: ION, 2021\n"
|
||||
"Language-Team: Hebrew (https://app.transifex.com/sabnzbd/teams/111101/he/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\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://app.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2021\n"
|
||||
"Language-Team: Dutch (https://app.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Polish (https://app.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://app.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Romanian (https://app.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Serbian (https://app.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Swedish (https://app.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha1\n"
|
||||
"Project-Id-Version: SABnzbd-4.2.0Alpha2\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Chinese (China) (https://app.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
|
||||
@@ -9,7 +9,7 @@ configobj==5.0.8
|
||||
cheroot==10.0.0
|
||||
six==1.16.0
|
||||
cherrypy==18.8.0
|
||||
jaraco.functools==3.9.0
|
||||
jaraco.functools==4.0.0
|
||||
jaraco.collections==4.3.0
|
||||
jaraco.text==3.8.1 # Newer version introduces irrelevant extra dependencies
|
||||
jaraco.classes==3.3.0
|
||||
|
||||
@@ -108,6 +108,7 @@ import sabnzbd.articlecache
|
||||
import sabnzbd.bpsmeter
|
||||
import sabnzbd.scheduler as scheduler
|
||||
import sabnzbd.notifier as notifier
|
||||
import sabnzbd.sorting
|
||||
from sabnzbd.decorators import synchronized
|
||||
import sabnzbd.utils.ssdp
|
||||
|
||||
@@ -138,7 +139,6 @@ DIR_PID = None
|
||||
|
||||
QUEUECOMPLETE = None # stores the nice name of the action
|
||||
QUEUECOMPLETEACTION = None # stores the name of the function to be called
|
||||
QUEUECOMPLETEARG = None # stores an extra arguments that need to be passed
|
||||
|
||||
DAEMON = None
|
||||
LINUX_POWER = powersup.HAVE_DBUS
|
||||
|
||||
@@ -592,9 +592,9 @@ def _api_addurl(name, kwargs):
|
||||
password = kwargs.get("password", "")
|
||||
|
||||
if name:
|
||||
nzo_id = sabnzbd.urlgrabber.add_url(name, pp, script, cat, priority, nzbname, password)
|
||||
# Reporting a list of NZO's, for compatibility with other add-methods
|
||||
return report(keyword="", data={"status": True, "nzo_ids": [nzo_id]})
|
||||
res, nzo_ids = sabnzbd.urlgrabber.add_url(name, pp, script, cat, priority, nzbname, password)
|
||||
return report(keyword="", data={"status": res is AddNzbFileResult.OK, "nzo_ids": nzo_ids})
|
||||
else:
|
||||
logging.info("API-call addurl: no URLs received")
|
||||
return report(_MSG_NO_VALUE)
|
||||
@@ -1513,7 +1513,7 @@ def retry_job(job, new_nzb=None, password=None):
|
||||
history_db = sabnzbd.get_db_connection()
|
||||
futuretype, url, pp, script, cat = history_db.get_other(job)
|
||||
if futuretype:
|
||||
nzo_id = sabnzbd.urlgrabber.add_url(url, pp, script, cat)
|
||||
nzo_id = sabnzbd.urlgrabber.add_url(url, pp, script, cat, dup_check=False)
|
||||
else:
|
||||
path = history_db.get_incomplete_path(job)
|
||||
nzo_id = sabnzbd.NzbQueue.repair_job(path, new_nzb, password)
|
||||
|
||||
@@ -36,6 +36,7 @@ from sabnzbd.filesystem import (
|
||||
diskspace,
|
||||
get_filename,
|
||||
has_unwanted_extension,
|
||||
get_basename,
|
||||
)
|
||||
from sabnzbd.constants import Status, GIGI, MAX_ASSEMBLER_QUEUE
|
||||
import sabnzbd.cfg as cfg
|
||||
@@ -249,7 +250,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"""
|
||||
fname = os.path.splitext(get_filename(path.lower()))[0]
|
||||
fname = get_basename(get_filename(path.lower()))
|
||||
for name in names:
|
||||
name = get_filename(name.lower())
|
||||
name, ext = os.path.splitext(name)
|
||||
|
||||
@@ -276,7 +276,7 @@ def validate_default_if_empty(root: str, value: str, default: str) -> Tuple[None
|
||||
##############################################################################
|
||||
# Special settings
|
||||
##############################################################################
|
||||
pre_script = OptionStr("misc", "pre_script", "None", validation=validate_script)
|
||||
|
||||
queue_complete = OptionStr("misc", "queue_complete")
|
||||
queue_complete_pers = OptionBool("misc", "queue_complete_pers", False)
|
||||
bandwidth_perc = OptionNumber("misc", "bandwidth_perc", 100, minval=0, maxval=100)
|
||||
@@ -375,6 +375,8 @@ ionice = OptionStr("misc", "ionice", validation=clean_nice_ionice_parameters)
|
||||
fail_hopeless_jobs = OptionBool("misc", "fail_hopeless_jobs", True)
|
||||
fast_fail = OptionBool("misc", "fast_fail", True)
|
||||
autodisconnect = OptionBool("misc", "auto_disconnect", True)
|
||||
pre_script = OptionStr("misc", "pre_script", "None", validation=validate_script)
|
||||
end_queue_script = OptionStr("misc", "end_queue_script", "None", validation=validate_script)
|
||||
no_dupes = OptionNumber("misc", "no_dupes", 0)
|
||||
no_series_dupes = OptionNumber("misc", "no_series_dupes", 0)
|
||||
series_propercheck = OptionBool("misc", "series_propercheck", True)
|
||||
@@ -448,7 +450,7 @@ wait_for_dfolder = OptionBool("misc", "wait_for_dfolder", False)
|
||||
rss_filenames = OptionBool("misc", "rss_filenames", False)
|
||||
api_logging = OptionBool("misc", "api_logging", True)
|
||||
html_login = OptionBool("misc", "html_login", True)
|
||||
warn_dupl_jobs = OptionBool("misc", "warn_dupl_jobs", True)
|
||||
warn_dupl_jobs = OptionBool("misc", "warn_dupl_jobs", False)
|
||||
helpful_warnings = OptionBool("misc", "helpful_warnings", True)
|
||||
keep_awake = OptionBool("misc", "keep_awake", True)
|
||||
tray_icon = OptionBool("misc", "tray_icon", True)
|
||||
|
||||
@@ -430,7 +430,7 @@ class ConfigServer:
|
||||
name = "servers," + self.__name
|
||||
|
||||
self.displayname = OptionStr(name, "displayname", add=False)
|
||||
self.host = OptionStr(name, "host", add=False)
|
||||
self.host = OptionStr(name, "host", validation=sabnzbd.cfg.all_lowercase, add=False)
|
||||
self.port = OptionNumber(name, "port", 119, 0, 2**16 - 1, add=False)
|
||||
self.timeout = OptionNumber(name, "timeout", 60, 20, 240, add=False)
|
||||
self.username = OptionStr(name, "username", add=False)
|
||||
|
||||
@@ -107,7 +107,6 @@ NORMAL_PRIORITY = 0
|
||||
LOW_PRIORITY = -1
|
||||
DEFAULT_PRIORITY = -100
|
||||
PAUSED_PRIORITY = -2
|
||||
DUP_PRIORITY = -3
|
||||
STOP_PRIORITY = -4
|
||||
|
||||
PP_LOOKUP = {0: "", 1: "R", 2: "U", 3: "D"}
|
||||
@@ -166,6 +165,13 @@ class Status:
|
||||
PROP = "Propagating" # Q: Delayed download
|
||||
|
||||
|
||||
class DuplicateStatus:
|
||||
DUPLICATE = "Duplicate" # Simple duplicate
|
||||
DUPLICATE_ALTERNATIVE = "Duplicate Alternative" # Alternative duplicate for a queued job
|
||||
SERIES_DUPLICATE = "Series Duplicate" # Simple Series duplicate
|
||||
SERIES_DUPLICATE_ALTERNATIVE = "Series Duplicate Alternative" # Alternative duplicate for a queued job
|
||||
|
||||
|
||||
class AddNzbFileResult:
|
||||
RETRY = "Retry" # File could not be read
|
||||
ERROR = "Error" # Rejected as duplicate, by pre-queue script or other failure to process file
|
||||
|
||||
@@ -321,15 +321,13 @@ class HistoryDB:
|
||||
|
||||
return items, total_items
|
||||
|
||||
def have_episode(self, series: str, season: str, episode: str) -> bool:
|
||||
def have_episode(self, series_key: str) -> bool:
|
||||
"""Check whether History contains this series episode"""
|
||||
total = 0
|
||||
if series and season and episode:
|
||||
pattern = "%s/%s/%s" % (series.lower(), season, episode)
|
||||
if self.execute(
|
||||
"""SELECT COUNT(*) FROM History WHERE series = ? AND STATUS != ?""", (pattern, Status.FAILED)
|
||||
):
|
||||
total = self.cursor.fetchone()["COUNT(*)"]
|
||||
if self.execute(
|
||||
"""SELECT COUNT(*) FROM History WHERE series = ? AND STATUS != ?""", (series_key, Status.FAILED)
|
||||
):
|
||||
total = self.cursor.fetchone()["COUNT(*)"]
|
||||
return total > 0
|
||||
|
||||
def have_name_or_md5sum(self, name: str, md5sum: str) -> bool:
|
||||
@@ -467,13 +465,8 @@ def build_history_info(nzo, workdir_complete: str, postproc_time: int, script_ou
|
||||
# Reuse the old 'report' column to indicate a URL-fetch
|
||||
report = "future" if nzo.futuretype else ""
|
||||
|
||||
# Analyze series info only when job is finished
|
||||
series = ""
|
||||
show_analysis = sabnzbd.newsunpack.analyse_show(nzo.final_name)
|
||||
if show_analysis["job_type"] == "tv":
|
||||
seriesname, season, episode = (show_analysis[key] for key in ("title", "season", "episode"))
|
||||
if seriesname and season and episode:
|
||||
series = "%s/%s/%s" % (seriesname.lower(), season, episode)
|
||||
# Make sure we have the duplicate key
|
||||
nzo.set_duplicate_series_key()
|
||||
|
||||
return (
|
||||
completed,
|
||||
@@ -497,7 +490,7 @@ def build_history_info(nzo, workdir_complete: str, postproc_time: int, script_ou
|
||||
nzo.fail_msg,
|
||||
url_info,
|
||||
nzo.bytes_downloaded,
|
||||
series,
|
||||
nzo.duplicate_series_key,
|
||||
nzo.md5sum,
|
||||
nzo.correct_password,
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ import os
|
||||
import re
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.filesystem import get_unique_filename, renamer, get_ext
|
||||
from sabnzbd.filesystem import get_unique_filename, renamer, get_ext, get_basename
|
||||
from sabnzbd.par2file import is_parfile, parse_par2_file
|
||||
import sabnzbd.utils.file_extension as file_extension
|
||||
from sabnzbd.misc import match_str
|
||||
@@ -299,7 +299,7 @@ def deobfuscate(nzo, filelist: List[str], usefulname: str):
|
||||
nr_files_renamed += 1
|
||||
|
||||
# Now find other files with the same basename in filelist, and rename them in the same way:
|
||||
basedirfile, _ = os.path.splitext(biggest_file) # something like "/home/this/myiso"
|
||||
basedirfile = get_basename(biggest_file) # something like "/home/this/myiso"
|
||||
for otherfile in filelist:
|
||||
if otherfile.startswith(basedirfile) and os.path.isfile(otherfile):
|
||||
# yes, same basedirfile, only different ending
|
||||
|
||||
@@ -30,7 +30,7 @@ from typing import Optional, Dict, List, Tuple
|
||||
import sabnzbd
|
||||
import sabnzbd.cfg as cfg
|
||||
from sabnzbd.misc import int_conv, format_time_string, build_and_run_command
|
||||
from sabnzbd.filesystem import long_path, remove_all, real_path, remove_file
|
||||
from sabnzbd.filesystem import long_path, remove_all, real_path, remove_file, get_basename
|
||||
from sabnzbd.nzbstuff import NzbObject, NzbFile
|
||||
from sabnzbd.encoding import platform_btou
|
||||
from sabnzbd.decorators import synchronized
|
||||
@@ -552,7 +552,7 @@ def analyze_rar_filename(filename):
|
||||
else:
|
||||
# Detect if first of "rxx" set
|
||||
if filename.endswith(".rar"):
|
||||
return os.path.splitext(filename)[0], 1
|
||||
return get_basename(filename), 1
|
||||
return None, None
|
||||
|
||||
|
||||
|
||||
@@ -503,7 +503,7 @@ class Downloader(Thread):
|
||||
|
||||
# Remove all connections to server
|
||||
for nw in server.idle_threads | server.busy_threads:
|
||||
self.__reset_nw(nw, "forcing disconnect", warn=False, wait=False, retry_article=False)
|
||||
self.__reset_nw(nw, "Forcing disconnect", warn=False, wait=False, retry_article=False)
|
||||
|
||||
# Make sure server address resolution is refreshed
|
||||
server.addrinfo = None
|
||||
@@ -570,7 +570,7 @@ class Downloader(Thread):
|
||||
# Already showed error
|
||||
self.__reset_nw(nw)
|
||||
else:
|
||||
self.__reset_nw(nw, "timed out", warn=True)
|
||||
self.__reset_nw(nw, "Timed out", warn=True)
|
||||
server.bad_cons += 1
|
||||
self.maybe_block_server(server)
|
||||
|
||||
@@ -630,14 +630,14 @@ class Downloader(Thread):
|
||||
server.host,
|
||||
sys.exc_info()[1],
|
||||
)
|
||||
self.__reset_nw(nw, "failed to initialize", warn=True)
|
||||
self.__reset_nw(nw, "Failed to initialize", warn=True)
|
||||
|
||||
if self.force_disconnect or self.shutdown:
|
||||
for server in self.servers:
|
||||
for nw in server.idle_threads | server.busy_threads:
|
||||
# Send goodbye if we have open socket
|
||||
if nw.nntp:
|
||||
self.__reset_nw(nw, "forcing disconnect", wait=False, count_article_try=False)
|
||||
self.__reset_nw(nw, "Forcing disconnect", wait=False, count_article_try=False)
|
||||
# Make sure server address resolution is refreshed
|
||||
server.addrinfo = None
|
||||
server.reset_article_queue()
|
||||
@@ -715,7 +715,7 @@ class Downloader(Thread):
|
||||
except ssl.SSLWantReadError:
|
||||
return
|
||||
except:
|
||||
self.__reset_nw(nw, "server closed connection", wait=False)
|
||||
self.__reset_nw(nw, "Server closed connection", wait=False)
|
||||
return
|
||||
|
||||
article = nw.article
|
||||
@@ -906,13 +906,14 @@ class Downloader(Thread):
|
||||
server.errormsg = errormsg
|
||||
logging.warning(errormsg)
|
||||
return False
|
||||
except:
|
||||
except Exception as err:
|
||||
logging.error(
|
||||
T("Connecting %s@%s failed, message=%s"),
|
||||
nw.thrdnum,
|
||||
nw.server.host,
|
||||
nw.nntp_msg,
|
||||
err,
|
||||
)
|
||||
logging.info("Traceback: ", exc_info=True)
|
||||
# No reset-warning needed, above logging is sufficient
|
||||
self.__reset_nw(nw, retry_article=False)
|
||||
return True
|
||||
@@ -983,11 +984,11 @@ class Downloader(Thread):
|
||||
self.add_socket(nw.nntp.fileno, nw)
|
||||
except socket.error as err:
|
||||
logging.info("Looks like server closed connection: %s", err)
|
||||
self.__reset_nw(nw, "server broke off connection", warn=True)
|
||||
self.__reset_nw(nw, "Server broke off connection", warn=True)
|
||||
except:
|
||||
logging.error(T("Suspect error in downloader"))
|
||||
logging.info("Traceback: ", exc_info=True)
|
||||
self.__reset_nw(nw, "server broke off connection", warn=True)
|
||||
self.__reset_nw(nw, "Server broke off connection", warn=True)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Timed restart of servers admin.
|
||||
|
||||
@@ -63,6 +63,11 @@ def get_ext(filename: str) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def get_basename(filename: str) -> str:
|
||||
"""Shorthand for getting the basename of a filename"""
|
||||
return os.path.splitext(filename)[0]
|
||||
|
||||
|
||||
def is_listed_ext(ext: str, ext_list: list) -> bool:
|
||||
"""Check if the extension is listed. In case of a regexp the entire extension must be matched;
|
||||
partial matches aren't accepted (e.g. 'r[0-9]{2}' will be treated the same as '^r[0-9]{2}$' and
|
||||
@@ -111,7 +116,7 @@ def get_filename(path: str) -> str:
|
||||
|
||||
def setname_from_path(path: str) -> str:
|
||||
"""Get the setname from a path"""
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
return get_basename(os.path.basename(path))
|
||||
|
||||
|
||||
def is_writable(path: str) -> bool:
|
||||
@@ -574,7 +579,7 @@ def list_scripts(default: bool = False, none: bool = True) -> List[str]:
|
||||
if (
|
||||
(
|
||||
sabnzbd.WIN32
|
||||
and os.path.splitext(script)[1].lower() in PATHEXT
|
||||
and get_ext(script) in PATHEXT
|
||||
and not win32api.GetFileAttributes(script) & win32file.FILE_ATTRIBUTE_HIDDEN
|
||||
)
|
||||
or script.endswith(".py")
|
||||
@@ -1213,8 +1218,7 @@ def wait_for_download_folder():
|
||||
|
||||
def backup_exists(filename: str) -> bool:
|
||||
"""Return True if backup exists and no_dupes is set"""
|
||||
path = sabnzbd.cfg.nzb_backup_dir.get_path()
|
||||
return path and os.path.exists(os.path.join(path, filename + ".gz"))
|
||||
return os.path.exists(os.path.join(sabnzbd.cfg.nzb_backup_dir.get_path(), filename + ".gz"))
|
||||
|
||||
|
||||
def backup_nzb(nzb_path: str):
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
sabnzbd.happyeyeballs - Python implementation of RFC 6555 / Happy Eyeballs: find the quickest IPv4/IPv6 connection
|
||||
"""
|
||||
|
||||
# Python implementation of RFC 6555 / Happy Eyeballs: find the quickest IPv4/IPv6 connection
|
||||
# Python implementation of RFC 6555/8305 (Happy Eyeballs): find the quickest IPv4/IPv6 connection
|
||||
# See https://tools.ietf.org/html/rfc6555
|
||||
# Method: Start parallel sessions using threads, and only wait for the quickest successful socket connect
|
||||
# See https://tools.ietf.org/html/rfc6555#section-4.1
|
||||
# We do not implement caching, as the lookup result is stored in the Server object
|
||||
# See https://tools.ietf.org/html/rfc8305
|
||||
|
||||
import socket
|
||||
import threading
|
||||
@@ -32,11 +30,36 @@ import logging
|
||||
import queue
|
||||
from dataclasses import dataclass
|
||||
from typing import Tuple, Union, Optional
|
||||
from more_itertools import roundrobin
|
||||
|
||||
from sabnzbd import cfg as cfg
|
||||
|
||||
# We always prefer IPv6 connections
|
||||
IP4_DELAY = 0.1
|
||||
# How long to delay between connection attempts? The RFC suggests 250ms, but this is
|
||||
# quite long and might give us a slow host that just happened to be on top of the list.
|
||||
# The absolute minium specified in RFC 8305 is 10ms, so we use that.
|
||||
CONNECTION_ATTEMPT_DELAY = 0.01
|
||||
|
||||
# The total time we want to wait for any result
|
||||
MAXIMUM_RESOLUTION_TIME = 3
|
||||
|
||||
# While providers are afraid to add IPv6 to their standard hostnames
|
||||
# we map a number of well known hostnames to their IPv6 alternatives.
|
||||
# WARNING: Only add if the SSL-certificate allows both hostnames!
|
||||
IPV6_MAPPING = {
|
||||
"news.eweka.nl": "news6.eweka.nl",
|
||||
"news.xlned.com": "news6.xlned.com",
|
||||
"news.usenet.farm": "news6.usenet.farm",
|
||||
"news.easynews.com": "news6.easynews.com",
|
||||
"news.tweaknews.nl": "news6.tweaknews.nl",
|
||||
"news.tweaknews.eu": "news6.tweaknews.eu",
|
||||
"news.astraweb.com": "news6.astraweb.com",
|
||||
"news.pureusenet.nl": "news6.pureusenet.nl",
|
||||
"news.sunnyusenet.com": "news6.sunnyusenet.com",
|
||||
"news.newshosting.com": "news6.newshosting.com",
|
||||
"news.usenetserver.com": "news6.usenetserver.com",
|
||||
"news.frugalusenet.com": "news-v6.frugalusenet.com",
|
||||
"eunews.frugalusenet.com": "eunews-v6.frugalusenet.com",
|
||||
}
|
||||
|
||||
|
||||
# For typing and convenience!
|
||||
@@ -55,71 +78,112 @@ class AddrInfo:
|
||||
|
||||
|
||||
# Called by each thread
|
||||
def do_socket_connect(result_queue: queue.Queue, addrinfo: AddrInfo, ipv4_delay: int):
|
||||
def do_socket_connect(result_queue: queue.Queue, addrinfo: AddrInfo):
|
||||
"""Connect to the ip, and put the result into the queue"""
|
||||
try:
|
||||
start = time.time()
|
||||
s = socket.socket(addrinfo.family, addrinfo.type)
|
||||
s.settimeout(3)
|
||||
|
||||
# Delay IPv4 connects in case we need it
|
||||
if ipv4_delay and addrinfo.family == socket.AddressFamily.AF_INET:
|
||||
time.sleep(ipv4_delay)
|
||||
|
||||
s.settimeout(MAXIMUM_RESOLUTION_TIME)
|
||||
try:
|
||||
s.connect(addrinfo.sockaddr)
|
||||
result_queue.put(addrinfo)
|
||||
logging.debug(
|
||||
"Happy Eyeballs connected to %s (%s) in %dms",
|
||||
addrinfo.ipaddress,
|
||||
addrinfo.canonname,
|
||||
1000 * (time.time() - start),
|
||||
)
|
||||
except socket.error:
|
||||
logging.debug(
|
||||
"Happy Eyeballs failed to connect to %s (%s) in %dms",
|
||||
addrinfo.ipaddress,
|
||||
addrinfo.canonname,
|
||||
1000 * (time.time() - start),
|
||||
)
|
||||
finally:
|
||||
s.close()
|
||||
result_queue.put((addrinfo, True))
|
||||
except:
|
||||
# We got an exception, so no successful connect on IP & port:
|
||||
result_queue.put((addrinfo, False))
|
||||
pass
|
||||
|
||||
|
||||
def happyeyeballs(host: str, port: int) -> Optional[AddrInfo]:
|
||||
"""Return the fastest result of getaddrinfo() based on RFC 6555 / Happy Eyeballs,
|
||||
"""Return the fastest result of getaddrinfo() based on RFC 6555/8305 (Happy Eyeballs),
|
||||
including IPv6 addresses if desired. Returns None in case no addresses were returned
|
||||
or if no connection could be made to any of the addresses"""
|
||||
by getaddrinfo or if no connection could be made to any of the addresses"""
|
||||
try:
|
||||
# Time how long it took us
|
||||
start = time.time()
|
||||
|
||||
# Get address information, by default both IPV4 and IPV6
|
||||
check_hosts = [host]
|
||||
family = socket.AF_UNSPEC
|
||||
if not cfg.ipv6_servers():
|
||||
family = socket.AF_INET
|
||||
elif host in IPV6_MAPPING:
|
||||
# See if we can add a IPv6 alternative
|
||||
check_hosts.append(IPV6_MAPPING[host])
|
||||
logging.info("Added alternative IPv6 address: %s", IPV6_MAPPING[host])
|
||||
|
||||
all_addrinfo = []
|
||||
ipv4_delay = 0
|
||||
ipv4_addrinfo = []
|
||||
ipv6_addrinfo = []
|
||||
last_canonname = ""
|
||||
for addrinfo in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM, flags=socket.AI_CANONNAME):
|
||||
# Convert to AddrInfo
|
||||
all_addrinfo.append(addrinfo := AddrInfo(*addrinfo))
|
||||
# We only want delay for IPv4 in case we got any IPv6
|
||||
if addrinfo.family == socket.AddressFamily.AF_INET6:
|
||||
ipv4_delay = IP4_DELAY
|
||||
# The canonname is only reported once per alias
|
||||
if addrinfo.canonname:
|
||||
last_canonname = addrinfo.canonname
|
||||
elif last_canonname:
|
||||
addrinfo.canonname = last_canonname
|
||||
logging.debug("Available addresses for %s (port=%d): %d", host, port, len(all_addrinfo))
|
||||
for check_host in check_hosts:
|
||||
try:
|
||||
for addrinfo in socket.getaddrinfo(
|
||||
check_host, port, family, socket.SOCK_STREAM, flags=socket.AI_CANONNAME
|
||||
):
|
||||
# Convert to AddrInfo
|
||||
addrinfo = AddrInfo(*addrinfo)
|
||||
|
||||
# Fill queue used for threads that will return the results
|
||||
# Even if there is just 1 result, we still check if we can connect
|
||||
result_queue: queue.Queue[Tuple[AddrInfo, bool]] = queue.Queue()
|
||||
for addrinfo in all_addrinfo:
|
||||
threading.Thread(target=do_socket_connect, args=(result_queue, addrinfo, ipv4_delay), daemon=True).start()
|
||||
# The canonname is only reported once per alias
|
||||
if addrinfo.canonname:
|
||||
last_canonname = addrinfo.canonname
|
||||
elif last_canonname:
|
||||
addrinfo.canonname = last_canonname
|
||||
|
||||
# start reading from the Queue for message from the threads:
|
||||
result = None
|
||||
for _ in range(len(all_addrinfo)):
|
||||
connect_result = result_queue.get()
|
||||
if connect_result[1]:
|
||||
result = connect_result[0]
|
||||
# Put it in the right list for further processing
|
||||
# But prevent adding duplicate items to the lists
|
||||
if addrinfo not in ipv6_addrinfo and addrinfo not in ipv4_addrinfo:
|
||||
if addrinfo.family == socket.AddressFamily.AF_INET6:
|
||||
ipv6_addrinfo.append(addrinfo)
|
||||
else:
|
||||
ipv4_addrinfo.append(addrinfo)
|
||||
except:
|
||||
# Did we fail on the first getaddrinfo already?
|
||||
# Otherwise, we failed on the IPv6 alternative address, and those failures can be ignored
|
||||
if not ipv4_addrinfo and not ipv6_addrinfo:
|
||||
raise
|
||||
|
||||
logging.debug(
|
||||
"Available addresses for %s (port=%d): %d IPv4 and %d IPv6",
|
||||
host,
|
||||
port,
|
||||
len(ipv4_addrinfo),
|
||||
len(ipv6_addrinfo),
|
||||
)
|
||||
|
||||
# To optimize success, the RFC states to alternate between trying the
|
||||
# IPv6 and IPv4 results, starting with IPv6 since it is the preferred method.
|
||||
result_queue: queue.Queue[AddrInfo] = queue.Queue()
|
||||
addr_tried = 0
|
||||
result: Optional[AddrInfo] = None
|
||||
for addrinfo in roundrobin(ipv6_addrinfo, ipv4_addrinfo):
|
||||
threading.Thread(target=do_socket_connect, args=(result_queue, addrinfo), daemon=True).start()
|
||||
addr_tried += 1
|
||||
try:
|
||||
result = result_queue.get(timeout=CONNECTION_ATTEMPT_DELAY)
|
||||
break
|
||||
except queue.Empty:
|
||||
# Start a thread for the next address in the list if the previous
|
||||
# connection attempt did not complete in time or if it wasn't a success
|
||||
continue
|
||||
|
||||
# If we had no results, we might just need to give it more time
|
||||
if not result:
|
||||
try:
|
||||
# Reduce waiting time by time already spent
|
||||
result = result_queue.get(timeout=MAXIMUM_RESOLUTION_TIME - addr_tried * CONNECTION_ATTEMPT_DELAY)
|
||||
except queue.Empty:
|
||||
raise ConnectionError("No addresses could be resolved")
|
||||
|
||||
logging.info("Quickest IP address for %s (port=%d): %s (%s)", host, port, result.ipaddress, result.canonname)
|
||||
logging.debug("Happy Eyeballs lookup and port connect took: %d ms", int(1000 * (time.time() - start)))
|
||||
return result
|
||||
except Exception as e:
|
||||
logging.debug("Failed Happy Eyeballs lookup: %s", e)
|
||||
|
||||
@@ -766,6 +766,7 @@ SWITCH_LIST = (
|
||||
"nice",
|
||||
"ionice",
|
||||
"pre_script",
|
||||
"end_queue_script",
|
||||
"pause_on_pwrar",
|
||||
"sfv_check",
|
||||
"deobfuscate_final_filenames",
|
||||
|
||||
@@ -52,7 +52,7 @@ from sabnzbd.constants import (
|
||||
import sabnzbd.config as config
|
||||
import sabnzbd.cfg as cfg
|
||||
from sabnzbd.encoding import ubtou
|
||||
from sabnzbd.filesystem import userxbit, make_script_path, remove_file, is_valid_script
|
||||
from sabnzbd.filesystem import userxbit, make_script_path, remove_file
|
||||
|
||||
if sabnzbd.WIN32:
|
||||
try:
|
||||
@@ -85,7 +85,14 @@ HAVE_AMPM = bool(time.strftime("%p"))
|
||||
|
||||
def helpful_warning(*args, **kwargs):
|
||||
"""Wrapper to ignore helpful warnings if desired"""
|
||||
if sabnzbd.cfg.helpful_warnings():
|
||||
if cfg.helpful_warnings():
|
||||
return logging.warning(*args, **kwargs)
|
||||
return logging.info(*args, **kwargs)
|
||||
|
||||
|
||||
def duplicate_warning(*args, **kwargs):
|
||||
"""Wrapper to ignore duplicate warnings if desired"""
|
||||
if cfg.warn_dupl_jobs():
|
||||
return logging.warning(*args, **kwargs)
|
||||
return logging.info(*args, **kwargs)
|
||||
|
||||
@@ -228,7 +235,7 @@ def cat_to_opts(cat, pp=None, script=None, priority=None) -> Tuple[str, int, str
|
||||
return cat, pp, script, priority
|
||||
|
||||
|
||||
def pp_to_opts(pp: int) -> Tuple[bool, bool, bool]:
|
||||
def pp_to_opts(pp: Optional[int]) -> Tuple[bool, bool, bool]:
|
||||
"""Convert numeric processing options to (repair, unpack, delete)"""
|
||||
# Convert the pp to an int
|
||||
pp = sabnzbd.interface.int_conv(pp)
|
||||
@@ -791,12 +798,13 @@ def format_time_string(seconds: float) -> str:
|
||||
return " ".join(completestr)
|
||||
|
||||
|
||||
def int_conv(value: Any) -> int:
|
||||
"""Safe conversion to int (can handle None)"""
|
||||
def int_conv(value: Any, default: Any = 0) -> int:
|
||||
"""Safe conversion to int (can handle None)
|
||||
Returns 0 or requested default value"""
|
||||
try:
|
||||
return int(value)
|
||||
except:
|
||||
return 0
|
||||
return default
|
||||
|
||||
|
||||
def create_https_certificates(ssl_cert, ssl_key):
|
||||
@@ -1161,15 +1169,14 @@ def run_command(cmd: List[str], **kwargs):
|
||||
return txt
|
||||
|
||||
|
||||
def run_script(script):
|
||||
"""Run a user script (queue complete only)"""
|
||||
script_path = make_script_path(script)
|
||||
if script_path:
|
||||
def run_script(script: str):
|
||||
"""Run a user script"""
|
||||
if script_path := make_script_path(script):
|
||||
try:
|
||||
script_output = run_command([script_path])
|
||||
logging.info("Output of queue-complete script %s: \n%s", script, script_output)
|
||||
script_output = run_command([script_path], env=sabnzbd.newsunpack.create_env())
|
||||
logging.info("Output of script %s: \n%s", script, script_output)
|
||||
except:
|
||||
logging.info("Failed queue-complete script %s, Traceback: ", script, exc_info=True)
|
||||
logging.info("Failed script %s, Traceback: ", script, exc_info=True)
|
||||
|
||||
|
||||
def set_socks5_proxy():
|
||||
@@ -1288,24 +1295,17 @@ def system_standby():
|
||||
|
||||
|
||||
def change_queue_complete_action(action: str, new: bool = True):
|
||||
"""Action or script to be performed once the queue has been completed
|
||||
Scripts are prefixed with 'script_'
|
||||
"""
|
||||
_action = None
|
||||
_argument = None
|
||||
"""Action or script to be performed once the queue has been completed"""
|
||||
function = None
|
||||
if new or cfg.queue_complete_pers():
|
||||
if action.startswith("script_") and is_valid_script(action.replace("script_", "", 1)):
|
||||
# all scripts are labeled script_xxx
|
||||
_action = sabnzbd.misc.run_script
|
||||
_argument = action.replace("script_", "", 1)
|
||||
elif action == "shutdown_pc":
|
||||
_action = system_shutdown
|
||||
if action == "shutdown_pc":
|
||||
function = system_shutdown
|
||||
elif action == "hibernate_pc":
|
||||
_action = system_hibernate
|
||||
function = system_hibernate
|
||||
elif action == "standby_pc":
|
||||
_action = system_standby
|
||||
function = system_standby
|
||||
elif action == "shutdown_program":
|
||||
_action = sabnzbd.shutdown_program
|
||||
function = sabnzbd.shutdown_program
|
||||
else:
|
||||
action = None
|
||||
else:
|
||||
@@ -1316,8 +1316,7 @@ def change_queue_complete_action(action: str, new: bool = True):
|
||||
config.save_config()
|
||||
|
||||
sabnzbd.QUEUECOMPLETE = action
|
||||
sabnzbd.QUEUECOMPLETEACTION = _action
|
||||
sabnzbd.QUEUECOMPLETEARG = _argument
|
||||
sabnzbd.QUEUECOMPLETEACTION = function
|
||||
|
||||
|
||||
def keep_awake():
|
||||
|
||||
@@ -36,7 +36,6 @@ import sabnzbd.utils.rarfile as rarfile
|
||||
from sabnzbd.misc import (
|
||||
format_time_string,
|
||||
find_on_path,
|
||||
int_conv,
|
||||
get_all_passwords,
|
||||
calc_age,
|
||||
cmp,
|
||||
@@ -45,7 +44,6 @@ from sabnzbd.misc import (
|
||||
format_time_left,
|
||||
)
|
||||
from sabnzbd.filesystem import (
|
||||
make_script_path,
|
||||
real_path,
|
||||
globber,
|
||||
globber_full,
|
||||
@@ -61,11 +59,12 @@ from sabnzbd.filesystem import (
|
||||
get_filename,
|
||||
SEVENMULTI_RE,
|
||||
is_size,
|
||||
get_basename,
|
||||
)
|
||||
from sabnzbd.nzbstuff import NzbObject
|
||||
import sabnzbd.cfg as cfg
|
||||
from sabnzbd.constants import Status, JOB_ADMIN
|
||||
from sabnzbd.sorting import Sorter
|
||||
|
||||
|
||||
# Regex globals
|
||||
RAR_V3_RE = re.compile(r"\.(?P<ext>part\d*)$", re.I)
|
||||
@@ -511,7 +510,7 @@ def rar_unpack(nzo: NzbObject, workdir_complete: str, one_folder: bool, rars: Li
|
||||
rar_set = setname_from_path(rar)
|
||||
if RAR_V3_RE.search(rar_set):
|
||||
# Remove the ".partXX" part
|
||||
rar_set = os.path.splitext(rar_set)[0]
|
||||
rar_set = get_basename(rar_set)
|
||||
if rar_set not in rar_sets:
|
||||
rar_sets[rar_set] = []
|
||||
rar_sets[rar_set].append(rar)
|
||||
@@ -878,7 +877,7 @@ def unseven(nzo: NzbObject, workdir_complete: str, one_folder: bool, sevens: Lis
|
||||
setname = setname_from_path(seven)
|
||||
if SEVENMULTI_RE.search(setname):
|
||||
# Remove the ".001" part
|
||||
setname = os.path.splitext(setname)[0]
|
||||
setname = get_basename(setname)
|
||||
if setname not in seven_sets:
|
||||
seven_sets[setname] = []
|
||||
seven_sets[setname].append(seven)
|
||||
@@ -1090,7 +1089,7 @@ def par2_repair(nzo: NzbObject, setname: str) -> Tuple[bool, bool]:
|
||||
|
||||
# Remove extra files created during repair and par2 base files
|
||||
for path in new_dir_content:
|
||||
if os.path.splitext(path)[1] == ".1" and path not in old_dir_content:
|
||||
if get_ext(path) == ".1" and path not in old_dir_content:
|
||||
deletables.append(os.path.join(nzo.download_path, path))
|
||||
deletables.append(os.path.join(nzo.download_path, setname + ".par2"))
|
||||
deletables.append(os.path.join(nzo.download_path, setname + ".PAR2"))
|
||||
@@ -2133,124 +2132,6 @@ def add_time_left(perc: float, start_time: Optional[float] = None, time_used: Op
|
||||
return " - %s %s" % (format_time_left(int((100 - perc) / (perc / time_used)), short_format=True), T("left"))
|
||||
return ""
|
||||
|
||||
|
||||
def analyse_show(name: str) -> Dict[str, str]:
|
||||
"""Use the Sorter to collect some basic info on series"""
|
||||
job = Sorter(
|
||||
None,
|
||||
name,
|
||||
None,
|
||||
None,
|
||||
force=True,
|
||||
sorter_config={
|
||||
"name": "newsunpack__analyse_show",
|
||||
"order": 0,
|
||||
"min_size": -1,
|
||||
"multipart_label": "",
|
||||
"sort_string": "",
|
||||
"sort_cats": [], # Categories and types are ignored when using the force
|
||||
"sort_type": [],
|
||||
"is_active": 1,
|
||||
},
|
||||
)
|
||||
job.get_values()
|
||||
return {
|
||||
"title": job.info.get("title", ""),
|
||||
"season": job.info.get("season_num", ""),
|
||||
"episode": job.info.get("episode_num", ""),
|
||||
"episode_name": job.info.get("ep_name", ""),
|
||||
"is_proper": job.is_proper(),
|
||||
"resolution": job.info.get("resolution", ""),
|
||||
"decade": job.info.get("decade", ""),
|
||||
"year": job.info.get("year", ""),
|
||||
"month": job.info.get("month", ""),
|
||||
"day": job.info.get("day", ""),
|
||||
"job_type": job.type,
|
||||
}
|
||||
|
||||
|
||||
def pre_queue(nzo: NzbObject, pp, cat):
|
||||
"""Run pre-queue script (if any) and process results.
|
||||
pp and cat are supplied separate since they can change.
|
||||
"""
|
||||
|
||||
def fix(p):
|
||||
# If added via API, some items can still be "None" (as a string)
|
||||
if not p or str(p).lower() == "none":
|
||||
return ""
|
||||
return str(p)
|
||||
|
||||
values = [1, nzo.final_name_with_password, pp, cat, nzo.script, nzo.priority, None]
|
||||
script_path = make_script_path(cfg.pre_script())
|
||||
if script_path:
|
||||
# Basic command-line parameters
|
||||
command = [
|
||||
script_path,
|
||||
nzo.final_name_with_password,
|
||||
pp,
|
||||
cat,
|
||||
nzo.script,
|
||||
nzo.priority,
|
||||
str(nzo.bytes),
|
||||
" ".join(nzo.groups),
|
||||
]
|
||||
command.extend(list(analyse_show(nzo.final_name_with_password).values()))
|
||||
command = [fix(arg) for arg in command]
|
||||
|
||||
# Fields not in the NZO directly
|
||||
extra_env_fields = {
|
||||
"groups": " ".join(nzo.groups),
|
||||
"show_name": command[8],
|
||||
"show_season": command[9],
|
||||
"show_episode": command[10],
|
||||
"show_episode_name": command[11],
|
||||
"proper": command[12],
|
||||
"resolution": command[13],
|
||||
"decade": command[14],
|
||||
"year": command[15],
|
||||
"month": command[16],
|
||||
"day": command[17],
|
||||
"type": command[18],
|
||||
}
|
||||
|
||||
try:
|
||||
p = build_and_run_command(command, env=create_env(nzo, extra_env_fields))
|
||||
except:
|
||||
logging.debug("Failed script %s, Traceback: ", script_path, exc_info=True)
|
||||
return values
|
||||
|
||||
output = p.stdout.read()
|
||||
ret = p.wait()
|
||||
logging.info("Pre-queue script returned %s and output=\n%s", ret, output)
|
||||
if ret == 0:
|
||||
split_output = output.splitlines()
|
||||
try:
|
||||
# Extract category line from pre-queue output
|
||||
pre_queue_category = split_output[3].strip(" '\"")
|
||||
except IndexError:
|
||||
pre_queue_category = None
|
||||
|
||||
for index, line in enumerate(split_output):
|
||||
line = line.strip(" '\"")
|
||||
if index < len(values):
|
||||
if line:
|
||||
values[index] = line
|
||||
elif pre_queue_category and index in (2, 4, 5):
|
||||
# Preserve empty pp, script, and priority lines to prevent
|
||||
# pre-existing values from overriding category-based settings
|
||||
values[index] = ""
|
||||
|
||||
accept = int_conv(values[0])
|
||||
if accept < 1:
|
||||
logging.info("Pre-Q refuses %s", nzo.final_name)
|
||||
elif accept == 2:
|
||||
logging.info("Pre-Q accepts&fails %s", nzo.final_name)
|
||||
else:
|
||||
logging.info("Pre-Q accepts %s", nzo.final_name)
|
||||
|
||||
return values
|
||||
|
||||
|
||||
def is_sevenfile(path: str) -> bool:
|
||||
"""Return True if path has 7Zip-signature and 7Zip is detected"""
|
||||
with open(path, "rb") as sevenzip:
|
||||
|
||||
@@ -199,7 +199,7 @@ class NewsWrapper:
|
||||
|
||||
# No data received
|
||||
if bytes_recv == 0:
|
||||
raise ConnectionError("server closed connection")
|
||||
raise ConnectionError("Server closed connection")
|
||||
|
||||
# Success, move timeout and internal data position
|
||||
self.timeout = time.time() + self.server.timeout
|
||||
|
||||
@@ -214,20 +214,20 @@ def process_nzb_archive_file(
|
||||
cat=cat,
|
||||
url=url,
|
||||
priority=priority,
|
||||
password=password,
|
||||
nzbname=nzbname,
|
||||
nzo_info=nzo_info,
|
||||
reuse=reuse,
|
||||
nzo_id=nzo_id,
|
||||
dup_check=dup_check,
|
||||
)
|
||||
if not nzo.password:
|
||||
nzo.password = password
|
||||
except (sabnzbd.nzbstuff.NzbEmpty, sabnzbd.nzbstuff.NzbRejected):
|
||||
# Empty or fully rejected
|
||||
pass
|
||||
except sabnzbd.nzbstuff.NzbRejectedToHistory as err:
|
||||
# Duplicate or unwanted extension that was failed to history
|
||||
nzo_ids.append(err.nzo_id)
|
||||
except sabnzbd.nzbstuff.NzbRejectToHistory as err:
|
||||
# Duplicate or unwanted extension directed to history
|
||||
sabnzbd.NzbQueue.fail_to_history(err.nzo)
|
||||
nzo_ids.append(err.nzo.nzo_id)
|
||||
except:
|
||||
# Something else is wrong, show error
|
||||
logging.error(T("Error while adding %s, removing"), name, exc_info=True)
|
||||
@@ -321,23 +321,23 @@ def process_single_nzb(
|
||||
cat=cat,
|
||||
url=url,
|
||||
priority=priority,
|
||||
password=password,
|
||||
nzbname=nzbname,
|
||||
nzo_info=nzo_info,
|
||||
reuse=reuse,
|
||||
nzo_id=nzo_id,
|
||||
dup_check=dup_check,
|
||||
)
|
||||
if not nzo.password:
|
||||
nzo.password = password
|
||||
except sabnzbd.nzbstuff.NzbEmpty:
|
||||
# Malformed or might not be an NZB file
|
||||
result = AddNzbFileResult.NO_FILES_FOUND
|
||||
except sabnzbd.nzbstuff.NzbRejected:
|
||||
# Rejected as duplicate or by pre-queue script
|
||||
result = AddNzbFileResult.ERROR
|
||||
except sabnzbd.nzbstuff.NzbRejectedToHistory as err:
|
||||
# Duplicate or unwanted extension that was failed to history
|
||||
nzo_ids.append(err.nzo_id)
|
||||
except sabnzbd.nzbstuff.NzbRejectToHistory as err:
|
||||
# Duplicate or unwanted extension directed to history
|
||||
sabnzbd.NzbQueue.fail_to_history(err.nzo)
|
||||
nzo_ids.append(err.nzo.nzo_id)
|
||||
except:
|
||||
# Something else is wrong, show error
|
||||
logging.error(T("Error while adding %s, removing"), filename, exc_info=True)
|
||||
|
||||
@@ -27,7 +27,7 @@ from typing import List, Dict, Union, Tuple, Optional
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.nzbstuff import NzbObject, Article
|
||||
from sabnzbd.misc import exit_sab, cat_to_opts, int_conv, caller_name, safe_lower
|
||||
from sabnzbd.misc import exit_sab, cat_to_opts, int_conv, caller_name, safe_lower, duplicate_warning
|
||||
from sabnzbd.filesystem import get_admin_path, remove_all, globber_full, remove_file, is_valid_script
|
||||
from sabnzbd.nzbparser import process_single_nzb
|
||||
from sabnzbd.panic import panic_queue
|
||||
@@ -37,7 +37,6 @@ from sabnzbd.constants import (
|
||||
QUEUE_VERSION,
|
||||
FUTURE_Q_FOLDER,
|
||||
JOB_ADMIN,
|
||||
DEFAULT_PRIORITY,
|
||||
LOW_PRIORITY,
|
||||
HIGH_PRIORITY,
|
||||
FORCE_PRIORITY,
|
||||
@@ -45,6 +44,7 @@ from sabnzbd.constants import (
|
||||
VERIFIED_FILE,
|
||||
Status,
|
||||
IGNORED_FILES_AND_FOLDERS,
|
||||
DuplicateStatus,
|
||||
)
|
||||
|
||||
import sabnzbd.cfg as cfg
|
||||
@@ -189,8 +189,7 @@ class NzbQueue:
|
||||
else:
|
||||
try:
|
||||
logging.debug("Repair job %s without stored NZB", name)
|
||||
nzo = NzbObject(name, nzbname=name, reuse=repair_folder)
|
||||
nzo.password = password
|
||||
nzo = NzbObject(name, password=password, nzbname=name, reuse=repair_folder)
|
||||
self.add(nzo)
|
||||
nzo_ids = [nzo.nzo_id]
|
||||
except:
|
||||
@@ -247,25 +246,6 @@ class NzbQueue:
|
||||
def set_top_only(self, value):
|
||||
self.__top_only = value
|
||||
|
||||
def generate_future(
|
||||
self, msg, pp=None, script=None, cat=None, url=None, priority=DEFAULT_PRIORITY, nzbname=None
|
||||
) -> NzbObject:
|
||||
"""Create and return a placeholder nzo object"""
|
||||
logging.debug("Creating placeholder NZO")
|
||||
future_nzo = NzbObject(
|
||||
filename=msg,
|
||||
pp=pp,
|
||||
script=script,
|
||||
futuretype=True,
|
||||
cat=cat,
|
||||
url=url,
|
||||
priority=priority,
|
||||
nzbname=nzbname,
|
||||
status=Status.GRABBING,
|
||||
)
|
||||
self.add(future_nzo)
|
||||
return future_nzo
|
||||
|
||||
def change_opts(self, nzo_ids: str, pp: int) -> int:
|
||||
result = 0
|
||||
for nzo_id in [item.strip() for item in nzo_ids.split(",")]:
|
||||
@@ -380,7 +360,7 @@ class NzbQueue:
|
||||
return nzo.nzo_id
|
||||
|
||||
@NzbQueueLocker
|
||||
def remove(self, nzo_id: str, cleanup: bool = True, delete_all_data: bool = True) -> Optional[str]:
|
||||
def remove(self, nzo_id: str, cleanup: bool = True, delete_all_data: bool = True) -> Optional[NzbObject]:
|
||||
"""Remove NZO from queue.
|
||||
It can be added to history directly.
|
||||
Or, we do some clean-up, sometimes leaving some data.
|
||||
@@ -396,18 +376,21 @@ class NzbQueue:
|
||||
nzo.status = Status.DELETED
|
||||
nzo.purge_data(delete_all_data=delete_all_data)
|
||||
self.save(False)
|
||||
return nzo_id
|
||||
return None
|
||||
return nzo
|
||||
|
||||
@NzbQueueLocker
|
||||
def remove_multiple(self, nzo_ids: List[str], delete_all_data=True) -> List[str]:
|
||||
"""Remove multiple jobs from the queue. Also triggers duplicate handling
|
||||
and downloader-disconnect, so intended for external use only!"""
|
||||
removed = []
|
||||
for nzo_id in nzo_ids:
|
||||
if self.remove(nzo_id, delete_all_data=delete_all_data):
|
||||
if nzo := self.remove(nzo_id, delete_all_data=delete_all_data):
|
||||
removed.append(nzo_id)
|
||||
# Start an alternative, if available
|
||||
self.handle_duplicate_alternatives(nzo, success=False)
|
||||
|
||||
# Any files left? Otherwise let's disconnect
|
||||
if self.actives(grabs=False) == 0 and cfg.autodisconnect():
|
||||
if not self.actives(grabs=False) and cfg.autodisconnect():
|
||||
# This was the last job, close server connections
|
||||
sabnzbd.Downloader.disconnect()
|
||||
|
||||
@@ -799,6 +782,13 @@ class NzbQueue:
|
||||
pass
|
||||
sabnzbd.Assembler.process(nzo)
|
||||
|
||||
def fail_to_history(self, nzo: NzbObject):
|
||||
"""Fail to history, with all the steps in between"""
|
||||
if not nzo.nzo_id:
|
||||
self.add(nzo, quiet=True)
|
||||
self.remove(nzo.nzo_id, cleanup=False)
|
||||
sabnzbd.PostProcessor.process(nzo)
|
||||
|
||||
def actives(self, grabs: bool = True) -> int:
|
||||
"""Return amount of non-paused jobs, optionally with 'grabbing' items
|
||||
Not locked for performance, only reads the queue
|
||||
@@ -956,5 +946,81 @@ class NzbQueue:
|
||||
lst.append((url, nzo))
|
||||
return lst
|
||||
|
||||
@NzbQueueLocker
|
||||
def have_name_or_md5sum(self, name: str, md5sum: str) -> bool:
|
||||
"""Check whether this name or md5sum is already
|
||||
in the queue or the post-processing queue"""
|
||||
lname = name.lower()
|
||||
for nzo in self.__nzo_list + sabnzbd.PostProcessor.get_queue():
|
||||
# Skip any jobs already marked as duplicate, to prevent double-triggers
|
||||
if not nzo.duplicate:
|
||||
# URL's do not have an MD5!
|
||||
if nzo.final_name.lower() == lname or (nzo.md5sum and md5sum and nzo.md5sum == md5sum):
|
||||
return True
|
||||
return False
|
||||
|
||||
@NzbQueueLocker
|
||||
def have_episode(self, series_key: str) -> bool:
|
||||
"""Check whether this episode of the series is already
|
||||
in the queue or the post-processing queue"""
|
||||
for nzo in self.__nzo_list:
|
||||
# Skip any jobs already marked as duplicate, to prevent double-triggers
|
||||
if not nzo.duplicate:
|
||||
if nzo.duplicate_series_key == series_key:
|
||||
return True
|
||||
return False
|
||||
|
||||
@NzbQueueLocker
|
||||
def handle_duplicate_alternatives(self, finished_nzo: NzbObject, success: bool):
|
||||
"""Remove matching duplicates if the first job succeeded,
|
||||
or start the next alternative if the job failed"""
|
||||
if not cfg.no_dupes() and not cfg.no_series_dupes():
|
||||
return
|
||||
|
||||
# Unfortunately we need a copy, since we might remove items from the list
|
||||
for nzo in self.__nzo_list[:]:
|
||||
if not nzo.duplicate:
|
||||
continue
|
||||
|
||||
# URL's do not have an MD5!
|
||||
if (
|
||||
nzo.final_name.lower() == finished_nzo.final_name.lower()
|
||||
or (nzo.md5sum and finished_nzo.md5sum and nzo.md5sum == finished_nzo.md5sum)
|
||||
) or (
|
||||
nzo.duplicate_series_key
|
||||
and finished_nzo.duplicate_series_key
|
||||
and nzo.duplicate_series_key == finished_nzo.duplicate_series_key
|
||||
):
|
||||
# Start the next alternative
|
||||
if not success:
|
||||
logging.info("Resuming duplicate alternative %s for ", nzo.final_name, finished_nzo.final_name)
|
||||
nzo.duplicate = None
|
||||
nzo.resume()
|
||||
return
|
||||
|
||||
# Take action on the alternatives to the duplicate
|
||||
# 1 = Discard
|
||||
# 2 = Pause
|
||||
# 3 = Fail (move to History)
|
||||
# 4 = Tag
|
||||
series_duplicate = nzo.duplicate == DuplicateStatus.SERIES_DUPLICATE_ALTERNATIVE
|
||||
if (not series_duplicate and cfg.no_dupes() == 1) or (series_duplicate and cfg.no_series_dupes() == 1):
|
||||
duplicate_warning(T('Ignoring duplicate NZB "%s"'), nzo.final_name)
|
||||
self.remove(nzo.nzo_id)
|
||||
elif (not series_duplicate and cfg.no_dupes() == 3) or (
|
||||
series_duplicate and cfg.no_series_dupes() == 3
|
||||
):
|
||||
duplicate_warning(T('Failing duplicate NZB "%s"'), nzo.final_name)
|
||||
nzo.fail_msg = T("Duplicate NZB")
|
||||
self.fail_to_history(nzo)
|
||||
else:
|
||||
# Action set to Pause or Tag, so only adjust the label on the first matching job
|
||||
logging.info("Re-tagging duplicate alternative %s for %s", nzo.final_name, finished_nzo.final_name)
|
||||
if nzo.duplicate == DuplicateStatus.DUPLICATE_ALTERNATIVE:
|
||||
nzo.duplicate = DuplicateStatus.DUPLICATE
|
||||
else:
|
||||
nzo.duplicate = DuplicateStatus.SERIES_DUPLICATE
|
||||
return
|
||||
|
||||
def __repr__(self):
|
||||
return "<NzbQueue>"
|
||||
|
||||
@@ -42,11 +42,11 @@ from sabnzbd.constants import (
|
||||
LOW_PRIORITY,
|
||||
DEFAULT_PRIORITY,
|
||||
PAUSED_PRIORITY,
|
||||
DUP_PRIORITY,
|
||||
STOP_PRIORITY,
|
||||
RENAMES_FILE,
|
||||
MAX_BAD_ARTICLES,
|
||||
Status,
|
||||
DuplicateStatus,
|
||||
)
|
||||
from sabnzbd.misc import (
|
||||
to_units,
|
||||
@@ -59,6 +59,7 @@ from sabnzbd.misc import (
|
||||
caller_name,
|
||||
opts_to_pp,
|
||||
pp_to_opts,
|
||||
duplicate_warning,
|
||||
)
|
||||
from sabnzbd.filesystem import (
|
||||
sanitize_foldername,
|
||||
@@ -79,6 +80,14 @@ from sabnzbd.filesystem import (
|
||||
is_valid_script,
|
||||
has_unwanted_extension,
|
||||
create_all_dirs,
|
||||
get_basename,
|
||||
backup_exists,
|
||||
get_new_id,
|
||||
save_data,
|
||||
load_data,
|
||||
save_compressed,
|
||||
backup_nzb,
|
||||
remove_data,
|
||||
)
|
||||
from sabnzbd.par2file import FilePar2Info
|
||||
from sabnzbd.decorators import synchronized
|
||||
@@ -228,7 +237,7 @@ class Article(TryList):
|
||||
def get_art_id(self):
|
||||
"""Return unique article storage name, create if needed"""
|
||||
if not self.art_id:
|
||||
self.art_id = sabnzbd.filesystem.get_new_id("article", self.nzf.nzo.admin_path)
|
||||
self.art_id = get_new_id("article", self.nzf.nzo.admin_path)
|
||||
return self.art_id
|
||||
|
||||
def search_new_server(self):
|
||||
@@ -342,7 +351,7 @@ class NzbFile(TryList):
|
||||
self.bytes_left: int = file_bytes
|
||||
|
||||
self.nzo: NzbObject = nzo
|
||||
self.nzf_id: str = sabnzbd.filesystem.get_new_id("nzf", nzo.admin_path)
|
||||
self.nzf_id: str = get_new_id("nzf", nzo.admin_path)
|
||||
self.deleted = False
|
||||
self.import_finished = False
|
||||
|
||||
@@ -366,7 +375,7 @@ class NzbFile(TryList):
|
||||
# Any articles left?
|
||||
if raw_article_db:
|
||||
# Save the rest
|
||||
sabnzbd.filesystem.save_data(raw_article_db, self.nzf_id, nzo.admin_path)
|
||||
save_data(raw_article_db, self.nzf_id, nzo.admin_path)
|
||||
else:
|
||||
# All imported
|
||||
self.import_finished = True
|
||||
@@ -374,8 +383,7 @@ class NzbFile(TryList):
|
||||
def finish_import(self):
|
||||
"""Load the article objects from disk"""
|
||||
logging.debug("Finishing import on %s", self.filename)
|
||||
raw_article_db = sabnzbd.filesystem.load_data(self.nzf_id, self.nzo.admin_path, remove=False)
|
||||
if raw_article_db:
|
||||
if raw_article_db := load_data(self.nzf_id, self.nzo.admin_path, remove=False):
|
||||
for raw_article in raw_article_db:
|
||||
self.add_article(raw_article)
|
||||
|
||||
@@ -505,9 +513,10 @@ class NzbRejected(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NzbRejectedToHistory(Exception):
|
||||
def __init__(self, nzo_id: str):
|
||||
self.nzo_id = nzo_id
|
||||
class NzbRejectToHistory(Exception):
|
||||
def __init__(self, nzo, fail_msg):
|
||||
self.nzo: NzbObject = nzo
|
||||
self.nzo.fail_msg = fail_msg
|
||||
super().__init__()
|
||||
|
||||
|
||||
@@ -554,6 +563,7 @@ NzbObjectSaver = (
|
||||
"encrypted",
|
||||
"bad_articles",
|
||||
"duplicate",
|
||||
"duplicate_series_key",
|
||||
"oversized",
|
||||
"precheck",
|
||||
"incomplete",
|
||||
@@ -585,6 +595,7 @@ class NzbObject(TryList):
|
||||
cat: Optional[str] = None,
|
||||
url: Optional[str] = None,
|
||||
priority: Optional[Union[int, str]] = DEFAULT_PRIORITY,
|
||||
password: Optional[str] = None,
|
||||
nzbname: Optional[str] = None,
|
||||
status: str = Status.QUEUED,
|
||||
nzo_info: Optional[Dict[str, Any]] = None,
|
||||
@@ -593,30 +604,29 @@ class NzbObject(TryList):
|
||||
dup_check: bool = True,
|
||||
):
|
||||
super().__init__()
|
||||
# Use original filename as basis
|
||||
self.work_name = self.filename = filename
|
||||
|
||||
self.filename = filename # Original filename
|
||||
if nzbname and nzb_fp:
|
||||
self.work_name = nzbname # Use nzbname if set and only for non-future slot
|
||||
else:
|
||||
self.work_name = filename
|
||||
# User defined job name
|
||||
if nzbname:
|
||||
self.final_name = self.work_name = nzbname
|
||||
|
||||
# For future-slots we keep the name given by URLGrabber
|
||||
if nzb_fp is None:
|
||||
self.final_name = self.work_name = filename
|
||||
else:
|
||||
# Remove trailing .nzb and .par(2)
|
||||
self.work_name = create_work_name(self.work_name)
|
||||
# Extract password if not explicitly set, also on URL-fetches which might have a custom name with password
|
||||
self.password = password
|
||||
if not self.password:
|
||||
# Extract before create_work_name, as it would escape the "/" on Windows
|
||||
self.work_name, self.password = scan_password(self.work_name)
|
||||
|
||||
# Extract password
|
||||
self.work_name, self.password = scan_password(self.work_name)
|
||||
if not self.work_name:
|
||||
# In case only /password was entered for nzbname
|
||||
self.work_name = filename
|
||||
# Check for password also in filename
|
||||
if not self.password:
|
||||
_, self.password = scan_password(get_basename(filename))
|
||||
|
||||
# Remove trailing .nzb/.par(2) and sanitize
|
||||
self.work_name = create_work_name(self.work_name)
|
||||
self.final_name = self.work_name
|
||||
|
||||
# Check for password also in filename
|
||||
if not self.password:
|
||||
_, self.password = scan_password(os.path.splitext(filename)[0])
|
||||
# Temporary store for custom job name for after URL-fetching
|
||||
self.custom_name = nzbname
|
||||
|
||||
# Create a record of the input for pp, script, and priority
|
||||
input_pp = pp
|
||||
@@ -671,19 +681,21 @@ class NzbObject(TryList):
|
||||
# The current status of the nzo eg:
|
||||
# Queued, Downloading, Repairing, Unpacking, Failed, Complete
|
||||
self.status: str = status
|
||||
|
||||
self.avg_bps_freq = 0
|
||||
self.avg_bps_total = 0
|
||||
|
||||
self.first_articles: List[Article] = []
|
||||
self.first_articles_count = 0
|
||||
self.saved_articles: Set[Article] = set()
|
||||
|
||||
self.nzo_id: Optional[str] = None
|
||||
|
||||
self.duplicate: Optional[str] = None
|
||||
self.duplicate_series_key: Optional[str] = None
|
||||
|
||||
self.futuretype = futuretype
|
||||
self.removed_from_queue = False
|
||||
self.to_be_removed = False
|
||||
self.duplicate = False
|
||||
self.oversized = False
|
||||
self.precheck = False
|
||||
self.incomplete = False
|
||||
@@ -703,9 +715,6 @@ class NzbObject(TryList):
|
||||
# Stores various info about the nzo to be
|
||||
self.nzo_info: Dict[str, Any] = nzo_info or {}
|
||||
|
||||
# Temporary store for custom foldername - needs to be stored because of url fetching
|
||||
self.custom_name = nzbname
|
||||
|
||||
self.next_save = None
|
||||
self.save_timeout = None
|
||||
self.encrypted = 0
|
||||
@@ -717,9 +726,14 @@ class NzbObject(TryList):
|
||||
# Path is empty in case of a future NZB
|
||||
self.download_path = ""
|
||||
|
||||
# This is a slot for a future NZB, ready now
|
||||
# It can also be a retry of a failed job with no extra NZB-file
|
||||
if nzb_fp is None and not reuse:
|
||||
# This is a slot for a future NZB, ready now
|
||||
# It can also be a retry of a failed job with no extra NZB-file
|
||||
# For future NZB, check if we don't already have this in the queue or history
|
||||
# based on the custom name supplied by the user or the RSS feed
|
||||
if self.custom_name and dup_check:
|
||||
self.duplicate_check()
|
||||
self.handle_duplicate_action()
|
||||
return
|
||||
|
||||
# Re-use existing nzo_id, when a "future" job gets it payload
|
||||
@@ -727,9 +741,6 @@ class NzbObject(TryList):
|
||||
self.nzo_id = nzo_id
|
||||
sabnzbd.NzbQueue.remove(nzo_id, delete_all_data=False)
|
||||
|
||||
# To be updated later if it's a duplicate
|
||||
duplicate = series_duplicate = False
|
||||
|
||||
# Apply conversion option to final folder
|
||||
if cfg.replace_spaces():
|
||||
logging.info("Replacing spaces with underscores in %s", self.final_name)
|
||||
@@ -765,7 +776,7 @@ class NzbObject(TryList):
|
||||
remove_all(admin_dir, "SABnzbd_article_*", keep_folder=True)
|
||||
|
||||
if nzb_fp:
|
||||
full_nzb_path = sabnzbd.filesystem.save_compressed(admin_dir, filename, nzb_fp)
|
||||
full_nzb_path = save_compressed(admin_dir, filename, nzb_fp)
|
||||
try:
|
||||
sabnzbd.nzbparser.nzbfile_parser(full_nzb_path, self)
|
||||
except Exception as err:
|
||||
@@ -783,11 +794,11 @@ class NzbObject(TryList):
|
||||
# Check against identical checksum or series/season/episode if not repair
|
||||
# Have to check for duplicate before saving the backup, as it will
|
||||
# trigger the duplicate-detection based on the backup
|
||||
if not reuse and dup_check and self.priority != REPAIR_PRIORITY:
|
||||
duplicate, series_duplicate = self.has_duplicates()
|
||||
if not reuse and dup_check and not self.duplicate and self.priority != REPAIR_PRIORITY:
|
||||
self.duplicate_check()
|
||||
|
||||
# Copy to backup
|
||||
sabnzbd.filesystem.backup_nzb(full_nzb_path)
|
||||
backup_nzb(full_nzb_path)
|
||||
|
||||
if not self.files and not reuse:
|
||||
self.purge_data()
|
||||
@@ -815,61 +826,15 @@ class NzbObject(TryList):
|
||||
# Determine category and find pp/script values
|
||||
self.cat, pp_tmp, self.script, priority = cat_to_opts(cat, pp, script, self.priority)
|
||||
self.set_priority(priority)
|
||||
self.repair, self.unpack, self.delete = pp_to_opts(pp_tmp)
|
||||
self.set_pp(pp_tmp)
|
||||
|
||||
# Show first meta-password (if any), when there's no explicit password
|
||||
if not self.password and self.meta.get("password"):
|
||||
self.password = self.meta.get("password", [None])[0]
|
||||
|
||||
# Run user pre-queue script if set and valid
|
||||
if not reuse and make_script_path(cfg.pre_script()):
|
||||
# Call the script
|
||||
accept, name, pp, cat_pp, script_pp, priority, group = sabnzbd.newsunpack.pre_queue(self, pp, cat)
|
||||
|
||||
if cat_pp:
|
||||
# An explicit pp/script/priority set upon adding the job takes precedence
|
||||
# over an implicit setting based on the category set by pre-queue
|
||||
if input_priority and not priority:
|
||||
priority = input_priority
|
||||
if input_pp and not pp:
|
||||
pp = input_pp
|
||||
if input_script and not script_pp:
|
||||
script_pp = input_script
|
||||
|
||||
# Accept or reject
|
||||
accept = int_conv(accept)
|
||||
if accept < 1:
|
||||
self.purge_data()
|
||||
raise NzbRejected
|
||||
if accept == 2:
|
||||
self.fail_msg = T("Pre-queue script marked job as failed")
|
||||
|
||||
# Process all options, only over-write if set by script
|
||||
# Beware that cannot do "if priority/pp", because those can
|
||||
# also have a valid value of 0, which shouldn't be ignored
|
||||
if name:
|
||||
self.set_final_name_and_scan_password(name)
|
||||
try:
|
||||
pp = int(pp)
|
||||
except:
|
||||
pp = None
|
||||
if cat_pp:
|
||||
cat = cat_pp
|
||||
try:
|
||||
priority = int(priority)
|
||||
except:
|
||||
priority = DEFAULT_PRIORITY
|
||||
if script_pp and is_valid_script(script_pp):
|
||||
script = script_pp
|
||||
if group:
|
||||
self.groups = [str(group)]
|
||||
|
||||
# Re-evaluate results from pre-queue script
|
||||
self.cat, pp, self.script, priority = cat_to_opts(cat, pp, script, priority)
|
||||
self.set_priority(priority)
|
||||
self.repair, self.unpack, self.delete = pp_to_opts(pp)
|
||||
else:
|
||||
accept = 1
|
||||
# Run user pre-queue script
|
||||
if not reuse:
|
||||
self.run_pre_queue(input_priority, input_pp, input_script)
|
||||
|
||||
# Pause if requested by the NZB-adding or the pre-queue script
|
||||
if self.priority == PAUSED_PRIORITY:
|
||||
@@ -884,57 +849,22 @@ class NzbObject(TryList):
|
||||
self.oversized = True
|
||||
self.priority = LOW_PRIORITY
|
||||
|
||||
# If the job is forced in any way, skip duplicate check
|
||||
if self.priority == FORCE_PRIORITY:
|
||||
duplicate = series_duplicate = False
|
||||
|
||||
# Handle duplicates
|
||||
if duplicate and (
|
||||
(not series_duplicate and cfg.no_dupes() == 1) or (series_duplicate and cfg.no_series_dupes() == 1)
|
||||
):
|
||||
if cfg.warn_dupl_jobs():
|
||||
logging.warning(T('Ignoring duplicate NZB "%s"'), filename)
|
||||
self.purge_data()
|
||||
raise NzbRejected
|
||||
|
||||
if duplicate and (
|
||||
(not series_duplicate and cfg.no_dupes() == 3) or (series_duplicate and cfg.no_series_dupes() == 3)
|
||||
):
|
||||
if cfg.warn_dupl_jobs():
|
||||
logging.warning(T('Failing duplicate NZB "%s"'), filename)
|
||||
# Move to history, utilizing the same code as accept&fail from pre-queue script
|
||||
self.fail_msg = T("Duplicate NZB")
|
||||
accept = 2
|
||||
duplicate = False
|
||||
|
||||
if duplicate or self.priority == DUP_PRIORITY:
|
||||
self.duplicate = True
|
||||
if cfg.no_dupes() == 4 or cfg.no_series_dupes() == 4:
|
||||
if cfg.warn_dupl_jobs():
|
||||
logging.warning('%s: "%s"', T("Duplicate NZB"), filename)
|
||||
else:
|
||||
if cfg.warn_dupl_jobs():
|
||||
logging.warning(T('Pausing duplicate NZB "%s"'), filename)
|
||||
self.pause()
|
||||
|
||||
# Only change priority if it's currently set to duplicate, otherwise keep original one
|
||||
if self.priority == DUP_PRIORITY:
|
||||
self.set_stateless_priority(self.cat)
|
||||
# Take action on the duplicate status
|
||||
self.handle_duplicate_action()
|
||||
|
||||
# Check if there is any unwanted extension in plain sight in the NZB itself
|
||||
for nzf in self.files:
|
||||
if cfg.action_on_unwanted_extensions() and has_unwanted_extension(nzf.filename):
|
||||
# ... we found an unwanted extension
|
||||
logging.warning(T("Unwanted Extension in file %s (%s)"), nzf.filename, self.final_name)
|
||||
# Pause, or Abort:
|
||||
if cfg.action_on_unwanted_extensions() == 1:
|
||||
logging.debug("Unwanted extension ... pausing")
|
||||
self.unwanted_ext = 1
|
||||
self.pause()
|
||||
if cfg.action_on_unwanted_extensions() == 2:
|
||||
logging.debug("Unwanted extension ... aborting")
|
||||
self.fail_msg = T("Aborted, unwanted extension detected")
|
||||
accept = 2
|
||||
if cfg.action_on_unwanted_extensions():
|
||||
for nzf in self.files:
|
||||
if has_unwanted_extension(nzf.filename):
|
||||
logging.warning(T("Unwanted Extension in file %s (%s)"), nzf.filename, self.final_name)
|
||||
# Pause, or Abort:
|
||||
if cfg.action_on_unwanted_extensions() == 1:
|
||||
logging.debug("Unwanted extension ... pausing")
|
||||
self.unwanted_ext = 1
|
||||
self.pause()
|
||||
if cfg.action_on_unwanted_extensions() == 2:
|
||||
logging.debug("Unwanted extension ... aborting")
|
||||
raise NzbRejectToHistory(self, T("Aborted, unwanted extension detected"))
|
||||
|
||||
if reuse:
|
||||
self.check_existing_files(self.download_path)
|
||||
@@ -951,14 +881,6 @@ class NzbObject(TryList):
|
||||
# Set nzo save-delay to minimum 120 seconds
|
||||
self.save_timeout = max(120, min(6.0 * self.bytes / GIGI, 300.0))
|
||||
|
||||
# In case pre-queue script or duplicate check want to move
|
||||
# to history we first need a nzo_id by entering the NzbQueue
|
||||
if accept == 2:
|
||||
sabnzbd.NzbQueue.add(self, quiet=True)
|
||||
sabnzbd.NzbQueue.end_job(self)
|
||||
# Raise error, so it's not added
|
||||
raise NzbRejectedToHistory(nzo_id=self.nzo_id)
|
||||
|
||||
def update_download_stats(self, bps, serverid, bytes_received):
|
||||
if bps:
|
||||
self.avg_bps_total += bps / 1024
|
||||
@@ -1255,7 +1177,7 @@ class NzbObject(TryList):
|
||||
existing_files = globber(wdir, "*.*")
|
||||
|
||||
# Substitute renamed files
|
||||
if renames := sabnzbd.filesystem.load_data(RENAMES_FILE, self.admin_path, remove=True):
|
||||
if renames := load_data(RENAMES_FILE, self.admin_path, remove=True):
|
||||
for name in renames:
|
||||
if name in existing_files or renames[name] in existing_files:
|
||||
if name in existing_files:
|
||||
@@ -1349,7 +1271,6 @@ class NzbObject(TryList):
|
||||
LOW_PRIORITY,
|
||||
DEFAULT_PRIORITY,
|
||||
PAUSED_PRIORITY,
|
||||
DUP_PRIORITY,
|
||||
STOP_PRIORITY,
|
||||
):
|
||||
self.priority = value
|
||||
@@ -1369,7 +1290,7 @@ class NzbObject(TryList):
|
||||
|
||||
for cat in cat_options:
|
||||
prio = cat_to_opts(cat)[3]
|
||||
if prio not in (DUP_PRIORITY, PAUSED_PRIORITY, FORCE_PRIORITY):
|
||||
if prio not in (PAUSED_PRIORITY, FORCE_PRIORITY):
|
||||
self.priority = prio
|
||||
break
|
||||
else:
|
||||
@@ -1379,8 +1300,10 @@ class NzbObject(TryList):
|
||||
def labels(self):
|
||||
"""Return (translated) labels of job"""
|
||||
labels = []
|
||||
if self.duplicate:
|
||||
if self.duplicate in (DuplicateStatus.DUPLICATE, DuplicateStatus.SERIES_DUPLICATE):
|
||||
labels.append(T("DUPLICATE"))
|
||||
if self.duplicate in (DuplicateStatus.DUPLICATE_ALTERNATIVE, DuplicateStatus.SERIES_DUPLICATE_ALTERNATIVE):
|
||||
labels.append(T("ALTERNATIVE"))
|
||||
if self.encrypted > 0:
|
||||
labels.append(T("ENCRYPTED"))
|
||||
if self.oversized:
|
||||
@@ -1446,7 +1369,7 @@ class NzbObject(TryList):
|
||||
# If user resumes after encryption warning, no more auto-pauses
|
||||
self.encrypted = 2
|
||||
# If user resumes after warning, reset duplicate/oversized/incomplete/unwanted indicators
|
||||
self.duplicate = False
|
||||
self.duplicate = None
|
||||
self.oversized = False
|
||||
self.incomplete = False
|
||||
if self.unwanted_ext:
|
||||
@@ -1506,7 +1429,8 @@ class NzbObject(TryList):
|
||||
|
||||
def abort_direct_unpacker(self):
|
||||
"""Abort any running DirectUnpackers"""
|
||||
if self.direct_unpacker:
|
||||
# During nzo creation the property doesn't exist yet
|
||||
if hasattr(self, "direct_unpacker") and self.direct_unpacker:
|
||||
self.direct_unpacker.abort()
|
||||
|
||||
def check_availability_ratio(self):
|
||||
@@ -1823,14 +1747,14 @@ class NzbObject(TryList):
|
||||
# Delete all, or just basic files
|
||||
if self.futuretype:
|
||||
# Remove temporary file left from URL-fetches
|
||||
sabnzbd.filesystem.remove_data(self.nzo_id, self.admin_path)
|
||||
remove_data(self.nzo_id, self.admin_path)
|
||||
elif delete_all_data:
|
||||
remove_all(self.download_path, recursive=True)
|
||||
else:
|
||||
# We remove any saved articles and save the renames file
|
||||
remove_all(self.download_path, "SABnzbd_nz?_*", keep_folder=True)
|
||||
remove_all(self.download_path, "SABnzbd_article_*", keep_folder=True)
|
||||
sabnzbd.filesystem.save_data(self.renames, RENAMES_FILE, self.admin_path, silent=True)
|
||||
save_data(self.renames, RENAMES_FILE, self.admin_path, silent=True)
|
||||
|
||||
def get_nzf_by_id(self, nzf_id: str) -> NzbFile:
|
||||
if nzf_id in self.files_table:
|
||||
@@ -1869,7 +1793,7 @@ class NzbObject(TryList):
|
||||
"""Save job's admin to disk"""
|
||||
self.save_attribs()
|
||||
if self.nzo_id and not self.removed_from_queue:
|
||||
sabnzbd.filesystem.save_data(self, self.nzo_id, self.admin_path)
|
||||
save_data(self, self.nzo_id, self.admin_path)
|
||||
|
||||
def save_attribs(self):
|
||||
"""Save specific attributes for Retry"""
|
||||
@@ -1877,11 +1801,11 @@ class NzbObject(TryList):
|
||||
for attrib in NzoAttributeSaver:
|
||||
attribs[attrib] = getattr(self, attrib)
|
||||
logging.debug("Saving attributes %s for %s", attribs, self.final_name)
|
||||
sabnzbd.filesystem.save_data(attribs, ATTRIB_FILE, self.admin_path, silent=True)
|
||||
save_data(attribs, ATTRIB_FILE, self.admin_path, silent=True)
|
||||
|
||||
def load_attribs(self) -> Tuple[Optional[str], Optional[int], Optional[str]]:
|
||||
"""Load saved attributes and return them to be parsed"""
|
||||
attribs = sabnzbd.filesystem.load_data(ATTRIB_FILE, self.admin_path, remove=False)
|
||||
attribs = load_data(ATTRIB_FILE, self.admin_path, remove=False)
|
||||
logging.debug("Loaded attributes %s for %s", attribs, self.final_name)
|
||||
|
||||
# If attributes file somehow does not exist
|
||||
@@ -1917,56 +1841,191 @@ class NzbObject(TryList):
|
||||
else:
|
||||
nzf_ids.remove(nzf_id)
|
||||
|
||||
def has_duplicates(self) -> Tuple[bool, bool]:
|
||||
"""Return (res, series)
|
||||
where "res" is True when this is a duplicate
|
||||
where "series" is True when this is an episode
|
||||
"""
|
||||
|
||||
no_dupes = cfg.no_dupes()
|
||||
no_series_dupes = cfg.no_series_dupes()
|
||||
series_propercheck = cfg.series_propercheck()
|
||||
|
||||
# Abort if dupe check is off for both nzb and series
|
||||
if not no_dupes and not no_series_dupes:
|
||||
return False, False
|
||||
|
||||
series = False
|
||||
res = False
|
||||
|
||||
with HistoryDB() as history_db:
|
||||
# Dupe check off nzb contents
|
||||
if no_dupes:
|
||||
res = history_db.have_name_or_md5sum(self.final_name, self.md5sum)
|
||||
logging.debug(
|
||||
"Duplicate checked NZB in history: filename=%s, md5sum=%s, result=%s",
|
||||
self.filename,
|
||||
self.md5sum,
|
||||
res,
|
||||
)
|
||||
if not res and cfg.backup_for_duplicates():
|
||||
res = sabnzbd.filesystem.backup_exists(self.filename)
|
||||
logging.debug("Duplicate checked NZB against backup: filename=%s, result=%s", self.filename, res)
|
||||
|
||||
# Dupe check off nzb filename
|
||||
if not res and no_series_dupes:
|
||||
show_analysis = sabnzbd.newsunpack.analyse_show(self.final_name)
|
||||
def set_duplicate_series_key(self):
|
||||
"""Shorthand to set the key once"""
|
||||
if not self.duplicate_series_key:
|
||||
show_analysis = sabnzbd.sorting.analyse_show(self.final_name)
|
||||
if show_analysis["job_type"] == "tv":
|
||||
series, season, episode, is_proper = (
|
||||
show_analysis[key] for key in ("title", "season", "episode", "is_proper")
|
||||
)
|
||||
if is_proper and series_propercheck:
|
||||
logging.debug("Dupe checking series+season+ep in history aborted due to PROPER/REAL/REPACK found")
|
||||
else:
|
||||
res = history_db.have_episode(series, season, episode)
|
||||
logging.debug(
|
||||
"Dupe checking series+season+ep in history: series=%s, season=%s, episode=%s, result=%s",
|
||||
series,
|
||||
season,
|
||||
episode,
|
||||
res,
|
||||
)
|
||||
# Ignore proper results if not desired
|
||||
if not cfg.series_propercheck():
|
||||
is_proper = False
|
||||
|
||||
return res, series
|
||||
# We allow 1 proper result to bypass duplicate detection
|
||||
self.duplicate_series_key = f"{series.lower()}/{season}/{episode}{f'/{is_proper}' if is_proper else ''}"
|
||||
|
||||
def duplicate_check(self):
|
||||
"""Set the correct duplicate status"""
|
||||
if not cfg.no_dupes() and not cfg.no_series_dupes():
|
||||
return
|
||||
|
||||
duplicate_in_history = series_duplicate_in_history = False
|
||||
duplicate_in_queue = series_duplicate_in_queue = False
|
||||
|
||||
with HistoryDB() as history_db:
|
||||
# Dupe check off just name or nzb contents
|
||||
if cfg.no_dupes():
|
||||
logging.debug("Duplicate checking NZB %s (md5sum=%s)", self.final_name, self.md5sum)
|
||||
|
||||
duplicate_in_history = history_db.have_name_or_md5sum(self.final_name, self.md5sum)
|
||||
logging.debug("Duplicate in history: %s", duplicate_in_history)
|
||||
|
||||
if not duplicate_in_history and cfg.backup_for_duplicates():
|
||||
duplicate_in_history = backup_exists(self.filename)
|
||||
logging.debug("Duplicate in backup: %s", duplicate_in_history)
|
||||
|
||||
duplicate_in_queue = sabnzbd.NzbQueue.have_name_or_md5sum(self.final_name, self.md5sum)
|
||||
logging.debug("Duplicate in queue: %s", duplicate_in_queue)
|
||||
|
||||
# Dupe check off nzb filename
|
||||
if not duplicate_in_history and not duplicate_in_queue and cfg.no_series_dupes():
|
||||
logging.debug("Duplicate episode checking (%s): %s", self.final_name, self.duplicate_series_key)
|
||||
self.set_duplicate_series_key()
|
||||
if self.duplicate_series_key:
|
||||
series_duplicate_in_history = history_db.have_episode(self.duplicate_series_key)
|
||||
logging.debug("Duplicate episode in history: %s", series_duplicate_in_history)
|
||||
|
||||
series_duplicate_in_queue = sabnzbd.NzbQueue.have_episode(self.duplicate_series_key)
|
||||
logging.debug("Duplicate episode in queue: %s", series_duplicate_in_queue)
|
||||
else:
|
||||
logging.debug("Not an episode, skipping duplicate episode check")
|
||||
|
||||
# Set the correct status
|
||||
if series_duplicate_in_queue:
|
||||
self.duplicate = DuplicateStatus.SERIES_DUPLICATE_ALTERNATIVE
|
||||
elif duplicate_in_queue:
|
||||
self.duplicate = DuplicateStatus.DUPLICATE_ALTERNATIVE
|
||||
elif series_duplicate_in_history:
|
||||
self.duplicate = DuplicateStatus.SERIES_DUPLICATE
|
||||
elif duplicate_in_history:
|
||||
self.duplicate = DuplicateStatus.DUPLICATE
|
||||
|
||||
def handle_duplicate_action(self):
|
||||
"""Handle duplicate detection action"""
|
||||
# If the job is set Force in any way, ignore results of duplicate check
|
||||
if self.priority == FORCE_PRIORITY:
|
||||
self.duplicate = None
|
||||
|
||||
# Take a direct action
|
||||
# 1 = Discard
|
||||
# 2 = Pause
|
||||
# 3 = Fail (move to History)
|
||||
# 4 = Tag
|
||||
if self.duplicate in (DuplicateStatus.DUPLICATE, DuplicateStatus.SERIES_DUPLICATE):
|
||||
series_duplicate = self.duplicate == DuplicateStatus.SERIES_DUPLICATE
|
||||
if (not series_duplicate and cfg.no_dupes() == 1) or (series_duplicate and cfg.no_series_dupes() == 1):
|
||||
# Discard
|
||||
duplicate_warning(T('Ignoring duplicate NZB "%s"'), self.final_name)
|
||||
self.purge_data()
|
||||
raise NzbRejected
|
||||
elif (not series_duplicate and cfg.no_dupes() == 3) or (series_duplicate and cfg.no_series_dupes() == 3):
|
||||
# Fail (move to History)
|
||||
duplicate_warning(T('Failing duplicate NZB "%s"'), self.final_name)
|
||||
raise NzbRejectToHistory(self, T("Duplicate NZB"))
|
||||
elif (not series_duplicate and cfg.no_dupes() == 2) or (series_duplicate and cfg.no_series_dupes() == 2):
|
||||
# Pause
|
||||
duplicate_warning(T('Pausing duplicate NZB "%s"'), self.final_name)
|
||||
self.pause()
|
||||
else:
|
||||
# Tag job
|
||||
duplicate_warning('%s: "%s"', T("Duplicate NZB"), self.final_name)
|
||||
|
||||
# In case of alternative, just pause
|
||||
if self.duplicate in (DuplicateStatus.DUPLICATE_ALTERNATIVE, DuplicateStatus.SERIES_DUPLICATE_ALTERNATIVE):
|
||||
logging.info("Pausing duplicate alternative %s", self.final_name)
|
||||
self.pause()
|
||||
|
||||
def run_pre_queue(
|
||||
self,
|
||||
input_priority: Optional[Union[int, str]],
|
||||
input_pp: Optional[int],
|
||||
input_script: Optional[str],
|
||||
):
|
||||
"""Run pre-queue script (if any) and process results."""
|
||||
if script_path := make_script_path(cfg.pre_script()):
|
||||
|
||||
def fix_parameter(parameter: Any) -> str:
|
||||
# If added via API, some items can still be "None" (as a string)
|
||||
if not parameter or str(parameter).lower() == "none":
|
||||
return ""
|
||||
return str(parameter)
|
||||
|
||||
# Basic parameters
|
||||
command = [script_path, self.final_name_with_password, self.cat, self.priority, self.pp, self.script]
|
||||
command = [fix_parameter(arg) for arg in command]
|
||||
|
||||
# Fields not in the NZO directly
|
||||
extra_env_fields = sabnzbd.newsunpack.analyse_show(self.final_name_with_password)
|
||||
extra_env_fields["groups"] = " ".join(self.groups)
|
||||
|
||||
try:
|
||||
p = sabnzbd.newsunpack.build_and_run_command(
|
||||
command, env=sabnzbd.newsunpack.create_env(self, extra_env_fields)
|
||||
)
|
||||
except:
|
||||
logging.debug("Failed script %s, Traceback: ", script_path, exc_info=True)
|
||||
return
|
||||
|
||||
output = p.stdout.read()
|
||||
ret = p.wait()
|
||||
logging.info("Pre-queue script returned %s and output=\n%s", ret, output)
|
||||
if ret == 0:
|
||||
# Base values
|
||||
pq_cat = pq_pp = pq_script = pq_priority = None
|
||||
for index, line in enumerate(output.splitlines(), start=1):
|
||||
# Make sure to keep this in line with the documentation!
|
||||
# 1: Accept
|
||||
# 2: Name
|
||||
# 3: Category
|
||||
# 4: Priority
|
||||
# 5: Post-processing
|
||||
# 6: Script
|
||||
# 7: Duplicate
|
||||
# 8: Duplicate key
|
||||
if line := line.strip(" '\""):
|
||||
if index == 1:
|
||||
# Accept or reject
|
||||
accept = int_conv(line)
|
||||
if accept < 1:
|
||||
logging.info("Pre-queue script refuses %s", self.final_name)
|
||||
self.purge_data()
|
||||
raise NzbRejected
|
||||
if accept == 2:
|
||||
logging.info("Pre-queue marking as failed %s", self.final_name)
|
||||
raise NzbRejectToHistory(self, T("Pre-queue script marked job as failed"))
|
||||
logging.info("Pre-queue accepts %s", self.final_name)
|
||||
elif index == 2:
|
||||
self.set_final_name_and_scan_password(line)
|
||||
elif index == 3:
|
||||
pq_cat = line
|
||||
elif index == 4:
|
||||
pq_priority = int_conv(line, default=DEFAULT_PRIORITY)
|
||||
elif index == 5:
|
||||
pq_pp = int_conv(line, default=None)
|
||||
elif index == 6:
|
||||
if is_valid_script(line):
|
||||
pq_script = line
|
||||
elif index == 7:
|
||||
self.duplicate = line
|
||||
elif index == 8:
|
||||
self.duplicate_series_key = line
|
||||
|
||||
if pq_cat:
|
||||
# An explicit pp/script/priority set upon adding the job takes precedence
|
||||
# over an implicit setting based on the category set by pre-queue
|
||||
if input_priority and pq_priority is None:
|
||||
pq_priority = input_priority
|
||||
if input_pp and pq_pp is None:
|
||||
pq_pp = input_pp
|
||||
if input_script and not pq_script:
|
||||
pq_script = input_script
|
||||
|
||||
# Re-evaluate results from pre-queue script
|
||||
self.cat, pp, self.script, priority = cat_to_opts(pq_cat, pq_pp, pq_script, pq_priority)
|
||||
self.set_priority(priority)
|
||||
self.set_pp(pp)
|
||||
|
||||
def __getstate__(self):
|
||||
"""Save to pickle file, selecting attributes"""
|
||||
|
||||
@@ -29,6 +29,7 @@ from typing import Dict, Optional, Tuple
|
||||
|
||||
from sabnzbd.constants import MEBI
|
||||
from sabnzbd.encoding import correct_unknown_encoding
|
||||
from sabnzbd.filesystem import get_basename
|
||||
|
||||
PROBABLY_PAR2_RE = re.compile(r"(.*)\.vol(\d*)[+\-](\d*)\.par2", re.I)
|
||||
SCAN_LIMIT = 10 * MEBI
|
||||
@@ -80,7 +81,7 @@ def analyse_par2(name: str, filepath: Optional[str] = None) -> Tuple[str, int, i
|
||||
block = m.group(3)
|
||||
else:
|
||||
# Base-par2 file
|
||||
setname = os.path.splitext(name)[0].strip()
|
||||
setname = get_basename(name).strip()
|
||||
# Could not parse the filename, need deep inspection
|
||||
# We already know it's a par2 from the is_parfile
|
||||
if filepath:
|
||||
|
||||
@@ -39,7 +39,14 @@ from sabnzbd.newsunpack import (
|
||||
is_sfv_file,
|
||||
)
|
||||
from threading import Thread
|
||||
from sabnzbd.misc import on_cleanup_list, is_sample, helpful_warning
|
||||
from sabnzbd.misc import (
|
||||
on_cleanup_list,
|
||||
is_sample,
|
||||
helpful_warning,
|
||||
history_updated,
|
||||
change_queue_complete_action,
|
||||
run_script,
|
||||
)
|
||||
from sabnzbd.filesystem import (
|
||||
real_path,
|
||||
get_unique_dir,
|
||||
@@ -172,7 +179,7 @@ class PostProcessor(Thread):
|
||||
else:
|
||||
self.slow_queue.put(nzo)
|
||||
self.save()
|
||||
sabnzbd.misc.history_updated()
|
||||
history_updated()
|
||||
|
||||
def remove(self, nzo: NzbObject):
|
||||
"""Remove given nzo from the queue"""
|
||||
@@ -181,7 +188,7 @@ class PostProcessor(Thread):
|
||||
except:
|
||||
pass
|
||||
self.save()
|
||||
sabnzbd.misc.history_updated()
|
||||
history_updated()
|
||||
|
||||
def stop(self):
|
||||
"""Stop thread after finishing running job"""
|
||||
@@ -398,7 +405,7 @@ def process_job(nzo: NzbObject) -> bool:
|
||||
return False
|
||||
|
||||
# If we don't need extra par2, we can disconnect
|
||||
if sabnzbd.NzbQueue.actives(grabs=False) == 0 and cfg.autodisconnect():
|
||||
if not sabnzbd.NzbQueue.actives(grabs=False) and cfg.autodisconnect():
|
||||
# This was the last job, close server connections
|
||||
sabnzbd.Downloader.disconnect()
|
||||
|
||||
@@ -593,6 +600,9 @@ def process_job(nzo: NzbObject) -> bool:
|
||||
# Force error for empty result
|
||||
all_ok = all_ok and not empty
|
||||
|
||||
# See if we need to start an alternative or remove the duplicates
|
||||
sabnzbd.NzbQueue.handle_duplicate_alternatives(nzo, all_ok)
|
||||
|
||||
except:
|
||||
logging.error(T("Post Processing Failed for %s (%s)"), filename, T("see logfile"))
|
||||
logging.info("Traceback: ", exc_info=True)
|
||||
@@ -658,7 +668,7 @@ def process_job(nzo: NzbObject) -> bool:
|
||||
# Purge items
|
||||
history_db.auto_history_purge()
|
||||
|
||||
sabnzbd.misc.history_updated()
|
||||
history_updated()
|
||||
return True
|
||||
|
||||
|
||||
@@ -718,7 +728,8 @@ def prepare_extraction_path(nzo: NzbObject) -> Tuple[str, str, Sorter, bool, Opt
|
||||
|
||||
# Is the unique path different? Then we also need to modify the final path
|
||||
if prefixed_path != tmp_workdir_complete:
|
||||
workdir_complete = workdir_complete + os.path.splitext(tmp_workdir_complete)[1]
|
||||
# The unique path adds an "extension"
|
||||
workdir_complete = workdir_complete + get_ext(tmp_workdir_complete)
|
||||
else:
|
||||
tmp_workdir_complete = workdir_complete
|
||||
|
||||
@@ -1040,20 +1051,20 @@ def rar_renamer(nzo: NzbObject) -> int:
|
||||
|
||||
def handle_empty_queue():
|
||||
"""Check if empty queue calls for action"""
|
||||
if sabnzbd.NzbQueue.actives() == 0:
|
||||
if not sabnzbd.NzbQueue.actives():
|
||||
sabnzbd.save_state()
|
||||
notifier.send_notification("SABnzbd", T("Queue finished"), "queue_done")
|
||||
|
||||
# Perform end-of-queue script
|
||||
if cfg.end_queue_script():
|
||||
logging.info("Queue has finished, launching script: %s ", cfg.end_queue_script())
|
||||
run_script(cfg.end_queue_script())
|
||||
|
||||
# Perform end-of-queue action when one is set
|
||||
if sabnzbd.QUEUECOMPLETEACTION:
|
||||
logging.info(
|
||||
"Queue has finished, launching: %s (%s)", sabnzbd.QUEUECOMPLETEACTION, sabnzbd.QUEUECOMPLETEARG
|
||||
)
|
||||
if sabnzbd.QUEUECOMPLETEARG:
|
||||
sabnzbd.QUEUECOMPLETEACTION(sabnzbd.QUEUECOMPLETEARG)
|
||||
else:
|
||||
Thread(target=sabnzbd.QUEUECOMPLETEACTION).start()
|
||||
sabnzbd.misc.change_queue_complete_action(cfg.queue_complete(), new=False)
|
||||
logging.info("Queue has finished, launching action: %s ", sabnzbd.QUEUECOMPLETEACTION)
|
||||
Thread(target=sabnzbd.QUEUECOMPLETEACTION).start()
|
||||
change_queue_complete_action(cfg.queue_complete(), new=False)
|
||||
|
||||
# Trigger garbage collection and release of memory
|
||||
logging.debug("Triggering garbage collection and release of memory")
|
||||
|
||||
@@ -27,7 +27,7 @@ import threading
|
||||
import urllib.parse
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.constants import RSS_FILE_NAME, DEFAULT_PRIORITY, DUP_PRIORITY
|
||||
from sabnzbd.constants import RSS_FILE_NAME, DEFAULT_PRIORITY
|
||||
from sabnzbd.decorators import synchronized
|
||||
import sabnzbd.config as config
|
||||
import sabnzbd.cfg as cfg
|
||||
@@ -308,7 +308,7 @@ class RSSReader:
|
||||
myPrio = defPrio
|
||||
n = 0
|
||||
if ("F" in reTypes or "S" in reTypes) and (not season or not episode):
|
||||
show_analysis = sabnzbd.newsunpack.analyse_show(title)
|
||||
show_analysis = sabnzbd.sorting.analyse_show(title)
|
||||
season, episode = show_analysis["season"], show_analysis["episode"]
|
||||
|
||||
# Match against all filters until an positive or negative match
|
||||
@@ -391,19 +391,6 @@ class RSSReader:
|
||||
elif not ((rePrios[n] != str(DEFAULT_PRIORITY)) or category):
|
||||
myPrio = catPrio
|
||||
|
||||
if cfg.no_dupes() and self.check_duplicate(title):
|
||||
if cfg.no_dupes() == 1:
|
||||
# Dupe-detection: Discard
|
||||
logging.info("Ignoring duplicate job %s", title)
|
||||
continue
|
||||
elif cfg.no_dupes() == 3:
|
||||
# Dupe-detection: Fail
|
||||
# We accept it so the Queue can send it to the History
|
||||
logging.info("Found duplicate job %s", title)
|
||||
else:
|
||||
# Dupe-detection: Pause
|
||||
myPrio = DUP_PRIORITY
|
||||
|
||||
act = download and not first
|
||||
if link in jobs:
|
||||
act = act and not jobs[link].get("status", "").endswith("*")
|
||||
@@ -546,18 +533,6 @@ class RSSReader:
|
||||
if self.jobs[feed][item]["status"] == "D":
|
||||
self.jobs[feed][item]["status"] = "D-"
|
||||
|
||||
def check_duplicate(self, title):
|
||||
"""Check if this title was in this or other feeds
|
||||
Return matching feed name
|
||||
"""
|
||||
title = title.lower()
|
||||
for fd in self.jobs:
|
||||
for lk in self.jobs[fd]:
|
||||
item = self.jobs[fd][lk]
|
||||
if item.get("status", " ")[0] == "D" and item.get("title", "").lower() == title:
|
||||
return fd
|
||||
return ""
|
||||
|
||||
|
||||
def patch_feedparser():
|
||||
"""Apply options that work for SABnzbd
|
||||
|
||||
@@ -169,7 +169,6 @@ SKIN_TEXT = {
|
||||
"mode": TT("Processing"), #: Queue page table column header
|
||||
"name": TT("Name"), #: Queue page table column header
|
||||
"button-retry": TT("Retry"), #: Queue page button
|
||||
"eoq-actions": TT("Actions"), #: Queue end-of-queue selection box
|
||||
"eoq-scripts": TT("Scripts"), #: Queue page table, script selection menu
|
||||
"purgeQueue": TT("Purge Queue"), #: Queue page button
|
||||
"purgeQueueConf": TT("Delete all items from the queue?"), #: Confirmation popup
|
||||
@@ -453,6 +452,8 @@ SKIN_TEXT = {
|
||||
),
|
||||
"opt-pre_script": TT("Pre-queue user script"),
|
||||
"explain-pre_script": TT("Used before an NZB enters the queue."),
|
||||
"opt-end_queue_script": TT("On queue finish script"),
|
||||
"explain-end_queue_script": TT("Executed after the queue finishes downloading."),
|
||||
"opt-par_option": TT("Extra PAR2 Parameters"),
|
||||
"explain-par_option": TT("Read the Wiki Help on this!"),
|
||||
"opt-nice": TT("Nice Parameters"),
|
||||
|
||||
@@ -73,8 +73,8 @@ class Sorter:
|
||||
self,
|
||||
nzo: Optional[NzbObject],
|
||||
job_name: str,
|
||||
path: str,
|
||||
cat: str,
|
||||
path: Optional[str] = None,
|
||||
cat: Optional[str] = None,
|
||||
force: Optional[bool] = False,
|
||||
sorter_config: Optional[dict] = None,
|
||||
):
|
||||
@@ -96,6 +96,9 @@ class Sorter:
|
||||
self.is_season_pack = False
|
||||
self.season_pack_setname = ""
|
||||
|
||||
self.match_sorters()
|
||||
|
||||
def match_sorters(self):
|
||||
# If a sorter configuration is passed as an argument, only use that one
|
||||
sorters = [self.sorter_config] if self.sorter_config else config.get_ordered_sorters()
|
||||
|
||||
@@ -260,7 +263,7 @@ class Sorter:
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
def is_proper(self):
|
||||
def is_proper(self) -> bool:
|
||||
"""Determine if the release is tagged 'Proper'. Note that guessit also sets this for similar
|
||||
tags such as 'Real' and 'Repack', saving us the trouble of checking for additional keywords."""
|
||||
if not self.guess:
|
||||
@@ -582,6 +585,40 @@ class Sorter:
|
||||
return move_to_parent_directory(base_path)
|
||||
|
||||
|
||||
class SeriesAnalyzer(Sorter):
|
||||
def __init__(self, job_name: str):
|
||||
"""Very basic sorter that doesn't require a config"""
|
||||
super().__init__(nzo=None, job_name=job_name)
|
||||
|
||||
def match_sorters(self):
|
||||
"""Much more basic matching"""
|
||||
self.guess = guess_what(self.original_job_name)
|
||||
|
||||
# Set the detected job type
|
||||
self.type = self.guess["type"]
|
||||
if self.guess["type"] == "episode":
|
||||
self.type = "date" if self.guess.get("date") else "tv"
|
||||
|
||||
|
||||
def analyse_show(job_name: str) -> Dict[str, str]:
|
||||
"""Use the Sorter to collect some basic info on series"""
|
||||
job = SeriesAnalyzer(job_name)
|
||||
job.get_values()
|
||||
return {
|
||||
"title": job.info.get("title", ""),
|
||||
"season": job.info.get("season_num", ""),
|
||||
"episode": job.info.get("episode_num", ""),
|
||||
"episode_name": job.info.get("ep_name", ""),
|
||||
"is_proper": job.is_proper(),
|
||||
"resolution": job.info.get("resolution", ""),
|
||||
"decade": job.info.get("decade", ""),
|
||||
"year": job.info.get("year", ""),
|
||||
"month": job.info.get("month", ""),
|
||||
"day": job.info.get("day", ""),
|
||||
"job_type": job.type,
|
||||
}
|
||||
|
||||
|
||||
def ends_in_file(path: str) -> bool:
|
||||
"""Return True when path ends with '.%ext' or '%fn' while allowing for a lowercase marker"""
|
||||
return bool(RE_ENDEXT.search(path) or RE_ENDFN.search(path))
|
||||
|
||||
@@ -31,7 +31,7 @@ from http.client import IncompleteRead, HTTPResponse
|
||||
from mailbox import Message
|
||||
from threading import Thread
|
||||
import base64
|
||||
from typing import Tuple, Optional, Union
|
||||
from typing import Tuple, Optional, Union, List
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.constants import DEF_TIMEOUT, FUTURE_Q_FOLDER, VALID_NZB_FILES, Status, VALID_ARCHIVES, DEFAULT_PRIORITY
|
||||
@@ -42,7 +42,7 @@ import sabnzbd.emailer as emailer
|
||||
import sabnzbd.notifier as notifier
|
||||
from sabnzbd.encoding import ubtou, utob
|
||||
from sabnzbd.nzbparser import AddNzbFileResult
|
||||
from sabnzbd.nzbstuff import NzbObject
|
||||
from sabnzbd.nzbstuff import NzbObject, NzbRejected, NzbRejectToHistory
|
||||
|
||||
|
||||
class URLGrabber(Thread):
|
||||
@@ -207,14 +207,6 @@ class URLGrabber(Thread):
|
||||
# Sometimes the filename contains the full URL, duh!
|
||||
filename = filename[filename.find("&nzbname=") + 9 :]
|
||||
|
||||
pp = future_nzo.pp
|
||||
script = future_nzo.script
|
||||
cat = future_nzo.cat
|
||||
if (cat is None or cat == "*") and category:
|
||||
cat = misc.cat_convert(category)
|
||||
priority = future_nzo.priority
|
||||
nzbname = future_nzo.custom_name
|
||||
|
||||
# process data
|
||||
if not data:
|
||||
try:
|
||||
@@ -246,11 +238,11 @@ class URLGrabber(Thread):
|
||||
if sabnzbd.filesystem.get_ext(filename) in VALID_ARCHIVES + VALID_NZB_FILES:
|
||||
res, _ = sabnzbd.nzbparser.add_nzbfile(
|
||||
path,
|
||||
pp=pp,
|
||||
script=script,
|
||||
cat=cat,
|
||||
priority=priority,
|
||||
nzbname=nzbname,
|
||||
pp=future_nzo.pp,
|
||||
script=future_nzo.script,
|
||||
cat=future_nzo.cat,
|
||||
priority=future_nzo.priority,
|
||||
nzbname=future_nzo.custom_name,
|
||||
nzo_info=nzo_info,
|
||||
url=future_nzo.url,
|
||||
keep=False,
|
||||
@@ -313,8 +305,7 @@ class URLGrabber(Thread):
|
||||
nzo.cat, _, nzo.script, _ = misc.cat_to_opts(nzo.cat, script=nzo.script)
|
||||
|
||||
# Add to history and run script if desired
|
||||
sabnzbd.NzbQueue.remove(nzo.nzo_id)
|
||||
sabnzbd.PostProcessor.process(nzo)
|
||||
sabnzbd.NzbQueue.fail_to_history(nzo)
|
||||
|
||||
|
||||
def _build_request(url: str) -> HTTPResponse:
|
||||
@@ -385,33 +376,46 @@ def add_url(
|
||||
pp: Optional[Union[int, str]] = None,
|
||||
script: Optional[str] = None,
|
||||
cat: Optional[str] = None,
|
||||
priority: Optional[Union[int, str]] = DEFAULT_PRIORITY,
|
||||
priority: Optional[Union[int, str]] = None,
|
||||
nzbname: Optional[str] = None,
|
||||
password: Optional[str] = None,
|
||||
):
|
||||
dup_check: bool = True,
|
||||
) -> Tuple[AddNzbFileResult, List[str]]:
|
||||
"""Add NZB based on a URL, attributes optional"""
|
||||
if not url.lower().startswith("http"):
|
||||
return
|
||||
if not pp or pp == "-1":
|
||||
pp = None
|
||||
if script and script.lower() == "default":
|
||||
script = None
|
||||
if cat and cat.lower() == "default":
|
||||
cat = None
|
||||
logging.info("Fetching %s", url)
|
||||
|
||||
# Add feed name if it came from RSS
|
||||
msg = T("Trying to fetch NZB from %s") % url
|
||||
if nzbname:
|
||||
msg = "%s - %s" % (nzbname, msg)
|
||||
return AddNzbFileResult.NO_FILES_FOUND, []
|
||||
|
||||
# Generate the placeholder
|
||||
future_nzo = sabnzbd.NzbQueue.generate_future(msg, pp, script, cat, url=url, priority=priority, nzbname=nzbname)
|
||||
logging.debug("Creating placeholder NZO for %s", url)
|
||||
msg = T("Trying to fetch NZB from %s") % url
|
||||
result: AddNzbFileResult = AddNzbFileResult.OK
|
||||
future_nzo = None
|
||||
nzo_ids = []
|
||||
try:
|
||||
future_nzo = NzbObject(
|
||||
filename=msg,
|
||||
pp=pp,
|
||||
script=script,
|
||||
futuretype=True,
|
||||
cat=cat,
|
||||
url=url,
|
||||
priority=priority,
|
||||
password=password,
|
||||
nzbname=nzbname,
|
||||
status=Status.GRABBING,
|
||||
dup_check=dup_check,
|
||||
)
|
||||
except NzbRejected:
|
||||
# Rejected as duplicate
|
||||
result = AddNzbFileResult.ERROR
|
||||
except NzbRejectToHistory as err:
|
||||
# Duplicate directed to history
|
||||
sabnzbd.NzbQueue.fail_to_history(err.nzo)
|
||||
nzo_ids.append(err.nzo.nzo_id)
|
||||
|
||||
# Set password
|
||||
if not future_nzo.password:
|
||||
future_nzo.password = password
|
||||
# Success
|
||||
if future_nzo:
|
||||
nzo_ids.append(sabnzbd.NzbQueue.add(future_nzo))
|
||||
sabnzbd.URLGrabber.add(url, future_nzo)
|
||||
|
||||
# Get it!
|
||||
sabnzbd.URLGrabber.add(url, future_nzo)
|
||||
return future_nzo.nzo_id
|
||||
return result, nzo_ids
|
||||
|
||||
@@ -103,16 +103,8 @@ def test_nntp_server_dict(kwargs):
|
||||
# Trying SSL on non-SSL port?
|
||||
if match_str(str(err), ("unknown protocol", "wrong version number")):
|
||||
return False, T("Unknown SSL protocol: Try disabling SSL or connecting on a different port.")
|
||||
|
||||
return False, str(err)
|
||||
|
||||
except TypeError:
|
||||
return False, T("Invalid server address.")
|
||||
|
||||
except IndexError:
|
||||
# No data was received in recv_chunk() call
|
||||
return False, T("Server quit during login sequence.")
|
||||
|
||||
except NNTPPermanentError:
|
||||
# Handled by the code below
|
||||
pass
|
||||
|
||||
@@ -45,6 +45,7 @@ class SysTrayIconThread(Thread):
|
||||
self.start()
|
||||
|
||||
def initialize(self):
|
||||
# Note that all functions should return True to prevent tracebacks
|
||||
message_map = {
|
||||
win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,
|
||||
win32con.WM_DESTROY: self.destroy,
|
||||
@@ -161,6 +162,7 @@ class SysTrayIconThread(Thread):
|
||||
|
||||
def restart(self, hwnd, msg, wparam, lparam):
|
||||
self.refresh_icon()
|
||||
return True
|
||||
|
||||
def destroy(self, hwnd, msg, wparam, lparam):
|
||||
if self.on_quit:
|
||||
@@ -168,6 +170,7 @@ class SysTrayIconThread(Thread):
|
||||
nid = (self.hwnd, 0)
|
||||
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
|
||||
win32gui.PostQuitMessage(0) # Terminate the app.
|
||||
return True
|
||||
|
||||
def notify(self, hwnd, msg, wparam, lparam):
|
||||
# Double click is actually 1 single click followed
|
||||
@@ -254,8 +257,8 @@ class SysTrayIconThread(Thread):
|
||||
return hbm
|
||||
|
||||
def command(self, hwnd, msg, wparam, lparam):
|
||||
id = win32gui.LOWORD(wparam)
|
||||
self.execute_menu_option(id)
|
||||
self.execute_menu_option(win32gui.LOWORD(wparam))
|
||||
return True
|
||||
|
||||
def execute_menu_option(self, id):
|
||||
menu_action = self.menu_actions_by_id[id]
|
||||
|
||||
@@ -25,7 +25,6 @@ import sys
|
||||
from random import sample
|
||||
|
||||
from sabnzbd.constants import (
|
||||
DUP_PRIORITY,
|
||||
PAUSED_PRIORITY,
|
||||
DEFAULT_PRIORITY,
|
||||
LOW_PRIORITY,
|
||||
@@ -46,7 +45,6 @@ from tests.testhelper import *
|
||||
# Define valid options for various stages
|
||||
PRIO_OPTS_ADD = [
|
||||
DEFAULT_PRIORITY,
|
||||
DUP_PRIORITY,
|
||||
PAUSED_PRIORITY,
|
||||
LOW_PRIORITY,
|
||||
NORMAL_PRIORITY,
|
||||
@@ -56,7 +54,6 @@ PRIO_OPTS_ADD = [
|
||||
]
|
||||
PRIO_OPTS_PREQ = [
|
||||
DEFAULT_PRIORITY,
|
||||
DUP_PRIORITY,
|
||||
PAUSED_PRIORITY,
|
||||
LOW_PRIORITY,
|
||||
NORMAL_PRIORITY,
|
||||
@@ -97,12 +94,11 @@ VALID_DEFAULT_PRIORITIES = [PAUSED_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, HIGH
|
||||
# Priorities that do *not* set a job state
|
||||
REGULAR_PRIOS = [LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, FORCE_PRIORITY]
|
||||
# Priorities that set job states
|
||||
STATE_PRIOS = [DUP_PRIORITY, PAUSED_PRIORITY]
|
||||
STATE_PRIOS = [PAUSED_PRIORITY]
|
||||
|
||||
# Needed for translating priority values to names
|
||||
ALL_PRIOS = {
|
||||
DEFAULT_PRIORITY: "Default",
|
||||
DUP_PRIORITY: "Duplicate",
|
||||
PAUSED_PRIORITY: "Paused",
|
||||
LOW_PRIORITY: "Low",
|
||||
NORMAL_PRIORITY: "Normal",
|
||||
@@ -178,9 +174,17 @@ class TestAddingNZBs:
|
||||
try:
|
||||
script_path = os.path.join(VAR.SCRIPT_DIR, script_name)
|
||||
with open(script_path, "w") as f:
|
||||
# line 1 = accept; 4 = category; 6 = priority
|
||||
# Lines:
|
||||
# 1: Accept
|
||||
# 2: Name
|
||||
# 3: Category
|
||||
# 4: Priority
|
||||
# 5: Post-processing
|
||||
# 6: Script
|
||||
# 7: Duplicate
|
||||
# 8: Duplicate key
|
||||
f.write(
|
||||
"#!%s\n\nprint('1\\n\\n\\n%s\\n\\n%s\\n')"
|
||||
"#!%s\n\nprint('1\\n\\n%s\\n%s\\n')"
|
||||
% (
|
||||
sys.executable,
|
||||
(category if category else ""),
|
||||
@@ -395,8 +399,6 @@ class TestAddingNZBs:
|
||||
assert ALL_PRIOS.get(expected_prio) == job["priority"]
|
||||
if expected_state:
|
||||
# Also check the correct state or label was set
|
||||
if expected_state == DUP_PRIORITY:
|
||||
assert "DUPLICATE" in job["labels"]
|
||||
if expected_state == PAUSED_PRIORITY:
|
||||
assert "Paused" == job["status"]
|
||||
|
||||
@@ -412,8 +414,8 @@ class TestAddingNZBs:
|
||||
@pytest.mark.parametrize("prio_def_cat", sample(VALID_DEFAULT_PRIORITIES, 2))
|
||||
@pytest.mark.parametrize("prio_add", sample(PRIO_OPTS_ADD, 3))
|
||||
@pytest.mark.parametrize("prio_add_cat", sample(PRIO_OPTS_ADD_CAT, 2))
|
||||
@pytest.mark.parametrize("prio_preq", sample(PRIO_OPTS_PREQ, 2))
|
||||
@pytest.mark.parametrize("prio_preq_cat", sample(PRIO_OPTS_PREQ_CAT, 2))
|
||||
@pytest.mark.parametrize("prio_preq", PRIO_OPTS_PREQ)
|
||||
@pytest.mark.parametrize("prio_preq_cat", PRIO_OPTS_PREQ_CAT)
|
||||
def test_adding_nzbs_priority_sample(
|
||||
self, prio_def_cat, prio_add, prio_add_cat, prio_preq, prio_preq_cat, prio_meta_cat
|
||||
):
|
||||
@@ -424,12 +426,8 @@ class TestAddingNZBs:
|
||||
[
|
||||
# Specific triggers for fixed bugs
|
||||
(-1, -2, None, None, None, None), # State-setting priorities always fell back to Normal
|
||||
(-1, -3, None, None, None, None),
|
||||
(1, None, -2, None, None, None),
|
||||
(2, None, None, -2, None, None),
|
||||
(2, None, None, -3, None, None),
|
||||
(2, -2, None, -3, None, None),
|
||||
(0, -3, None, None, None, None),
|
||||
(0, 2, None, None, 1, None), # Explicit priority on add was bested by implicit from pre-queue
|
||||
(1, None, None, None, -1, None), # Category-based values from pre-queue didn't work at all
|
||||
# Checks for test code regressions
|
||||
@@ -439,12 +437,9 @@ class TestAddingNZBs:
|
||||
(-2, None, -2, None, 2, None),
|
||||
(-2, None, -1, None, 1, None),
|
||||
(2, None, -1, None, -2, None),
|
||||
(-2, -3, 1, None, None, None),
|
||||
(2, 2, None, -2, None, None),
|
||||
(2, 1, None, -2, None, None),
|
||||
(1, -2, 0, None, None, None),
|
||||
(0, -3, None, None, 1, None),
|
||||
(0, -1, -1, -3, 2, None),
|
||||
(0, 2, None, -2, None, -1),
|
||||
(1, -2, -100, None, None, -1),
|
||||
(1, None, None, None, None, -1),
|
||||
@@ -600,9 +595,10 @@ class TestAddingNZBs:
|
||||
assert job["priority"] == ALL_PRIOS.get(expected_prio)
|
||||
if expected_prio == FORCE_PRIORITY:
|
||||
assert "DUPLICATE" not in job["labels"]
|
||||
assert "ALTERNATIVE" not in job["labels"]
|
||||
assert job["status"] == "Downloading"
|
||||
else:
|
||||
assert "DUPLICATE" in job["labels"]
|
||||
assert "ALTERNATIVE" in job["labels"]
|
||||
assert job["status"] == "Paused"
|
||||
|
||||
self._clear_and_reset_backup_directory(backup_dir)
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
"""
|
||||
tests.test_functional_adding_nzbs_clean - Tests for settings interaction when adding NZBs (clean SABnzbd instance)
|
||||
"""
|
||||
|
||||
import time
|
||||
from zipfile import ZipFile
|
||||
import tests.test_functional_adding_nzbs as test_functional_adding_nzbs
|
||||
from sabnzbd.constants import STOP_PRIORITY
|
||||
from tests.testhelper import *
|
||||
|
||||
|
||||
@@ -43,32 +44,42 @@ class TestAddingNZBsClean:
|
||||
|
||||
# Test for both normal and zipped version
|
||||
for nzbfile in (basenzbfile, zipnzbfile):
|
||||
# Add backup directory for duplicate detection
|
||||
backup_dir = self._add_backup_directory()
|
||||
# Pause the queue at first
|
||||
assert get_api_result(mode="pause")["status"] is True
|
||||
|
||||
# Add the job a first time
|
||||
job = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile})
|
||||
assert job["status"]
|
||||
assert job["nzo_ids"]
|
||||
job1 = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile})
|
||||
assert job1["status"]
|
||||
assert job1["nzo_ids"]
|
||||
|
||||
# 1=Discard, should return False and no nzo_ids
|
||||
# 1=Discard
|
||||
self._api_set_config("no_dupes", 1)
|
||||
|
||||
# Add the job a second time
|
||||
job = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile})
|
||||
assert not job["status"]
|
||||
assert not job["nzo_ids"]
|
||||
# Add the job a second time, it should be added with ALTERNATIVE label
|
||||
job2 = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile})
|
||||
assert job2["status"]
|
||||
assert job2["nzo_ids"]
|
||||
queue = get_api_result(mode="queue", extra_arguments={"nzo_ids": job2["nzo_ids"][0]})
|
||||
job_in_queue = queue["queue"]["slots"][0]
|
||||
assert "ALTERNATIVE" in job_in_queue["labels"]
|
||||
assert job_in_queue["status"] == "Paused"
|
||||
|
||||
# 3=Fail to history, should return True and nzo_ids
|
||||
self._api_set_config("no_dupes", 3)
|
||||
job = get_api_result(mode="addlocalfile", extra_arguments={"name": nzbfile})
|
||||
assert job["status"]
|
||||
assert job["nzo_ids"]
|
||||
time.sleep(1)
|
||||
assert not get_api_result(mode="queue", extra_arguments={"nzo_ids": job["nzo_ids"][0]})["queue"]["slots"]
|
||||
assert get_api_result(mode="history", extra_arguments={"nzo_ids": job["nzo_ids"][0]})["history"]["slots"]
|
||||
# Stop the first job
|
||||
get_api_result(
|
||||
mode="queue", extra_arguments={"name": "priority", "value": job1["nzo_ids"][0], "value2": STOP_PRIORITY}
|
||||
)
|
||||
|
||||
# Reset
|
||||
# Wait for the job to be removed
|
||||
time.sleep(2)
|
||||
assert get_api_result(mode="history", extra_arguments={"nzo_ids": job1["nzo_ids"][0]})["history"]["slots"]
|
||||
|
||||
# Now the second job should no longer be paused and labelled
|
||||
queue = get_api_result(mode="queue", extra_arguments={"nzo_ids": job2["nzo_ids"][0]})
|
||||
job_in_queue = queue["queue"]["slots"][0]
|
||||
assert "ALTERNATIVE" not in job_in_queue["labels"]
|
||||
assert job_in_queue["status"] == "Queued"
|
||||
|
||||
# Reset duplicate detection
|
||||
self._api_set_config("no_dupes", 0)
|
||||
|
||||
# Test unwanted extensions Fail to history
|
||||
@@ -86,4 +97,7 @@ class TestAddingNZBsClean:
|
||||
mode="set_config_default",
|
||||
extra_arguments={"keyword": ["unwanted_extensions", "action_on_unwanted_extensions"]},
|
||||
)
|
||||
self._clear_and_reset_backup_directory(backup_dir)
|
||||
|
||||
# Delete all jobs from queue and history
|
||||
for mode in ("queue", "history"):
|
||||
get_api_result(mode=mode, extra_arguments={"name": "delete", "value": "all", "del_files": 1})
|
||||
|
||||
@@ -610,16 +610,7 @@ class TestQueueApi(ApiTestFunctions):
|
||||
(True, False, "hibernate_pc"),
|
||||
(True, False, "standby_pc"),
|
||||
(True, True, "shutdown_program"),
|
||||
(True, True, "script_Sample-PostProc.py"),
|
||||
(False, False, "script_Sample-PostProc.py"),
|
||||
(False, False, "invalid_option"),
|
||||
(False, True, "script_foobar.py"), # Doesn't exist, see issue #1650
|
||||
(False, True, "script_" + os.path.join("..", "SABnzbd.py")), # Outside the scriptsdir, #1650 again
|
||||
(False, True, "script_" + os.path.join("..", "..", "SABnzbd.py")),
|
||||
(False, True, "script_" + os.path.join("..", "..", "..", "SABnzbd.py")),
|
||||
(False, True, "script_"), # Empty after removal of the prefix
|
||||
(True, True, "script_my_script_for_sab.py"), # Test for #1651
|
||||
(False, True, "my_script_for_sab.py"),
|
||||
],
|
||||
)
|
||||
def test_api_queue_change_complete_action(self, should_work, set_scriptsdir, value):
|
||||
@@ -627,12 +618,6 @@ class TestQueueApi(ApiTestFunctions):
|
||||
# queue and add some random job before setting any end-of-queue actions.
|
||||
self._create_random_queue(minimum_size=1)
|
||||
|
||||
# Setup the script_dir as ordered
|
||||
script_dir = ""
|
||||
if set_scriptsdir:
|
||||
script_dir = "scripts"
|
||||
self._setup_script_dir(script_dir, script="my_script_for_sab.py")
|
||||
|
||||
# Run the queue complete action api call
|
||||
prev_value = self._get_api_json("queue")["queue"]["finishaction"]
|
||||
json = self._get_api_json("queue", extra_args={"name": "change_complete_action", "value": value})
|
||||
|
||||
@@ -19,10 +19,13 @@
|
||||
tests.test_happyeyeballs - Testing SABnzbd happyeyeballs
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
|
||||
import pytest
|
||||
from flaky import flaky
|
||||
|
||||
from sabnzbd.happyeyeballs import happyeyeballs
|
||||
from sabnzbd.happyeyeballs import happyeyeballs, IPV6_MAPPING
|
||||
|
||||
|
||||
@flaky
|
||||
@@ -57,3 +60,12 @@ class TestHappyEyeballs:
|
||||
def test_nntp(self):
|
||||
ip = happyeyeballs("news.newshosting.com", port=119).ipaddress
|
||||
assert "." in ip or ":" in ip
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith("darwin"), reason="Resolves strangely on macOS CI")
|
||||
@pytest.mark.parametrize("hostname", IPV6_MAPPING.keys())
|
||||
def test_ipv6_mapping(self, hostname):
|
||||
# This test will let us remove hostnames from the mapping
|
||||
# once the providers add IPv6 to their main hostname
|
||||
with pytest.raises(socket.gaierror):
|
||||
# Print results for us to see the new information
|
||||
print(socket.getaddrinfo(hostname, 119, socket.AF_INET6, socket.SOCK_STREAM))
|
||||
|
||||
@@ -219,6 +219,7 @@ class FakeHistoryDB(db.HistoryDB):
|
||||
nzo.repair, nzo.unpack, nzo.delete = pp_to_opts(choice(list(PP_LOOKUP.keys()))) # for "pp"
|
||||
nzo.nzo_info = {"download_time": randint(1, 10**4)}
|
||||
nzo.unpack_info = {"unpack_info": "placeholder unpack_info line\r\n" * 3}
|
||||
nzo.duplicate_series_key = "show/season/episode"
|
||||
nzo.futuretype = False # for "report", only True when fetching an URL
|
||||
nzo.download_path = os.path.join(os.path.dirname(db.HistoryDB.db_path), "placeholder_downpath")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user