Compare commits

...

17 Commits

Author SHA1 Message Date
Safihre
1e3e4b4118 Update text files for 2.3.4RC1 2018-05-19 18:24:01 +02:00
Safihre
87dfbe34d4 Use local Windows MailSlot address
In WIndows 10 April Creators update this stopped working.
https://forums.sabnzbd.org/viewtopic.php?f=3&t=23370
2018-05-14 20:11:22 +02:00
Safihre
c56bcfaf61 Only the HTTP status code 200 is required
Closes #1146
2018-05-14 19:45:28 +02:00
Safihre
a947a1d88b Always send NNTP QUIT after server-test 2018-05-14 11:07:48 +02:00
Safihre
ad0d5726ec Add option "--disable-file-log" to disable file-based logging
Closes #1103.
2018-05-10 10:52:56 +02:00
Safihre
c52ce58b6d Handle filenames in redirected URL's better
Originated from https://www.reddit.com/r/usenet/comments/8gfjky/this_started_happening_recently_what_could_be/
2018-05-10 10:17:40 +02:00
Sander
a90356c6e7 Automatically whitelist ".local" or ".local.", aka mDNS name (#1141)
Closes #1138
2018-05-04 16:53:57 +02:00
Safihre
5c78c7855b Use 64bit unrar 5.5.0 compatible with ElCapitan 2018-05-03 08:02:52 +02:00
Safihre
915ee650ee Add CORS * header
Closes #1136
2018-04-30 08:38:53 +02:00
Safihre
58bd12b083 Correctly lowercase host_whitelist
@sanderjo is right, this should always happen no matter how option saved.
2018-04-28 18:02:14 +02:00
Safihre
ecc334360a Auto-detected hostname should be lowercased
https://forums.sabnzbd.org/viewtopic.php?f=3&t=23352
2018-04-25 19:14:45 +02:00
Safihre
1f04343a4d Update text files for 2.3.3 2018-04-22 18:56:38 +02:00
SABnzbd Automation
70f8509f6e Automatic translation update 2018-04-21 18:57:45 +00:00
jcfp
74a97296a5 Accept cheetah version newer than 2.x
I'm going to update cheetah to v. 3.x in debian soonish. All seems to work fine with sab in a quick test, apart from this version check.
2018-04-21 16:41:28 +02:00
Safihre
45d3440443 Multi-archive and split-files can also have more than 999 parts
https://forums.sabnzbd.org/viewtopic.php?f=3&t=23338
2018-04-18 09:23:19 +02:00
Safihre
c872ee16ab Changing Server priority would give JSON-page 2018-04-17 15:53:09 +02:00
Safihre
da473424f2 Bump SABYenc to 3.3.5 2018-04-17 15:52:20 +02:00
16 changed files with 97 additions and 90 deletions

View File

@@ -1,5 +1,5 @@
*******************************************
*** This is SABnzbd 2.3.3 ***
*** This is SABnzbd 2.3.4 ***
*******************************************
SABnzbd is an open-source cross-platform binary newsreader.
It simplifies the process of downloading from Usenet dramatically,

View File

@@ -1,4 +1,4 @@
SABnzbd 2.3.3
SABnzbd 2.3.4
-------------------------------------------------------------------------------
0) LICENSE

View File

@@ -1,7 +1,7 @@
Metadata-Version: 1.0
Name: SABnzbd
Version: 2.3.3RC2
Summary: SABnzbd-2.3.3RC2
Version: 2.3.4RC1
Summary: SABnzbd-2.3.4RC1
Home-page: https://sabnzbd.org
Author: The SABnzbd Team
Author-email: team@sabnzbd.org

View File

@@ -1,44 +1,16 @@
Release Notes - SABnzbd 2.3.3 RC 2
Release Notes - SABnzbd 2.3.4 RC 1
=========================================================
## Changes since 2.3.3 RC 1
- Hostname check improved for IPv6 addresses
- Category not correctly parsed when grabbing NZB from URL
- Unpacked zip/7zip files were not sorted
- Extended SAN list of newly generated self-signed certificates
## Changes since 2.3.3 Beta 1
- SABYenc updated to 3.3.4 to fix (more) false-positive CRC errors
- Failed URL fetches also trigger post-processing script (if configured)
- Added option to disable "X-Frame-Options" HTTP-header
- Added option to set maximum URL fetch retries
## Changes since 2.3.2
- Introduce and enforce "host_whitelist" to reject DNS Rebinding attacks.
If you access SABnzbd from a non-standard URL, you will need to add
the hostname. More info: https://sabnzbd.org/hostname-check
- SABYenc updated to 3.3.3 to fix false-positive CRC errors
- SSL-Ciphers can now be set per-server
- Added "X-Frame-Options" HTTP-header to prevent click-jacking
- Added "httpOnly" HTTP-header to prevent script cookie access
- Added "ignore_empty_files" option to not warn on empty files in NZB
- Indicate that SMPL-skin is no longer supported
- Removed undocumented "callback" option from API calls
- macOS: 64bit version of unrar instead of 32bit
- Windows: Set process priority of external processes (unpack/repair)
- Windows: Default external process priority increased to "Normal"
## Bugfixes since 2.3.2
- NZB's can be added via command-line but this was not shown in "--help"
- Language-change via API would not only change language after restart
- Correctly indicate that 99 is maximum server priority
- Only show SSL-warning if it was actually tested
- Media files with "password" in filename were detected as encrypted
- Servers that could not be DNS-resolved could block the queue
- Detect '502 Byte limit exceeded' as payment problem
- Server load-balancing setting was ignored when testing server
- Windows: MultiPar checksum errors during repair would result in crash
- Windows: Update 7zip to 18.01
## Changes since 2.3.3
- Device hostname in hostname-verification always lowercased
- Hostnames ending in ".local" are always accepted
- URLGrabber would not always detect correct filename
- URLGrabber would ignore some successful downloads
- Always send NNTP QUIT after server-test
- Added option "--disable-file-log" to disable file-based logging
- Added CORS-header to API
- Windows: Service compatibility with Windows 10 April update
- macOS: Restore compatibility with El Capitan (10.11)
## Upgrading from 2.2.x and older
- Finish queue

View File

@@ -44,7 +44,7 @@ import re
try:
import Cheetah
if Cheetah.Version[0] != '2':
if Cheetah.Version[0] < '2':
raise ValueError
except ValueError:
print "Sorry, requires Python module Cheetah 2.0rc7 or higher."
@@ -204,6 +204,7 @@ def print_help():
print " --ipv6_hosting <0|1> Listen on IPv6 address [::1] [*]"
print " --no-login Start with username and password reset"
print " --log-all Log all article handling (for developers)"
print " --disable-file-log Logging is only written to console"
print " --console Force console logging for OSX app"
print " --new Run a new instance of SABnzbd"
print ""
@@ -760,7 +761,7 @@ def commandline_handler(frozen=True):
opts, args = getopt.getopt(info, "phdvncwl:s:f:t:b:2:",
['pause', 'help', 'daemon', 'nobrowser', 'clean', 'logging=',
'weblogging', 'server=', 'templates', 'ipv6_hosting=',
'template2', 'browser=', 'config-file=', 'force',
'template2', 'browser=', 'config-file=', 'force', 'disable-file-log',
'version', 'https=', 'autorestarted', 'repair', 'repair-all',
'log-all', 'no-login', 'pid=', 'new', 'console', 'pidfile=',
# Below Win32 Service options
@@ -823,6 +824,7 @@ def main():
cherrypylogging = None
clean_up = False
logging_level = None
no_file_log = False
web_dir = None
vista_plus = False
win64 = False
@@ -896,6 +898,8 @@ def main():
pause = True
elif opt in ('--log-all',):
sabnzbd.LOG_ALL = True
elif opt in ('--disable-file-log'):
no_file_log = True
elif opt in ('--no-login',):
no_login = True
elif opt in ('--pid',):
@@ -1076,11 +1080,7 @@ def main():
# We found a port, now we never check again
sabnzbd.cfg.fixed_ports.set(True)
if logging_level is None:
logging_level = sabnzbd.cfg.log_level()
else:
sabnzbd.cfg.log_level.set(logging_level)
# Logging-checks
logdir = sabnzbd.cfg.log_dir.get_path()
if fork and not logdir:
print "Error:"
@@ -1099,19 +1099,24 @@ def main():
# Prevent the logger from raising exceptions
# primarily to reduce the fallout of Python issue 4749
logging.raiseExceptions = 0
# Log-related constants we always need
if logging_level is None:
logging_level = sabnzbd.cfg.log_level()
else:
sabnzbd.cfg.log_level.set(logging_level)
sabnzbd.LOGFILE = os.path.join(logdir, DEF_LOG_FILE)
logformat = '%(asctime)s::%(levelname)s::[%(module)s:%(lineno)d] %(message)s'
logger.setLevel(LOGLEVELS[logging_level + 1])
try:
rollover_log = logging.handlers.RotatingFileHandler(
sabnzbd.LOGFILE, 'a+',
sabnzbd.cfg.log_size.get_int(),
sabnzbd.cfg.log_backups())
logformat = '%(asctime)s::%(levelname)s::[%(module)s:%(lineno)d] %(message)s'
rollover_log.setFormatter(logging.Formatter(logformat))
sabnzbd.LOGHANDLER = rollover_log
logger.addHandler(rollover_log)
logger.setLevel(LOGLEVELS[logging_level + 1])
if not no_file_log:
rollover_log = logging.handlers.RotatingFileHandler(
sabnzbd.LOGFILE, 'a+',
sabnzbd.cfg.log_size.get_int(),
sabnzbd.cfg.log_backups())
rollover_log.setFormatter(logging.Formatter(logformat))
logger.addHandler(rollover_log)
except IOError:
print "Error:"
@@ -1141,6 +1146,8 @@ def main():
console.setLevel(LOGLEVELS[logging_level + 1])
console.setFormatter(logging.Formatter(logformat))
logger.addHandler(console)
if no_file_log:
logging.info('Console logging only')
if noConsoleLoggingOSX:
logging.info('Console logging for OSX App disabled')
so = file('/dev/null', 'a+')
@@ -1365,8 +1372,11 @@ def main():
staticcfg = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(sabnzbd.WEB_DIR_CONFIG, 'staticcfg'), 'tools.staticdir.content_types': forced_mime_types}
wizard_static = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(sabnzbd.WIZARD_DIR, 'static'), 'tools.staticdir.content_types': forced_mime_types}
appconfig = {'/api': {'tools.basic_auth.on': False},
'/rss': {'tools.basic_auth.on': False},
appconfig = {'/api': {
'tools.basic_auth.on': False,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Access-Control-Allow-Origin', '*')]
},
'/static': static,
'/wizard/static': wizard_static,
'/favicon.ico': {'tools.staticfile.on': True, 'tools.staticfile.filename': os.path.join(sabnzbd.WEB_DIR_CONFIG, 'staticcfg', 'ico', 'favicon.ico')},

View File

@@ -415,6 +415,8 @@
// Exception when change of priority, reload
\$('input[name="priority"], input[name="displayname"]').on('change', function() {
\$('.fullform').submit(function() {
// No ajax this time
\$('input[name="ajax"]').val('')
// Skip the fancy stuff, just submit
this.submit()
})

View File

Binary file not shown.

View File

@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: sabnzbd\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2018-03-15 13:08+0000\n"
"PO-Revision-Date: 2018-02-14 14:17+0000\n"
"Last-Translator: Safihre <safihre@sabnzbd.org>\n"
"PO-Revision-Date: 2018-04-15 21:22+0000\n"
"Last-Translator: ciho <Unknown>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2018-03-16 05:37+0000\n"
"X-Generator: Launchpad (build 18571)\n"
"X-Launchpad-Export-Date: 2018-04-16 05:40+0000\n"
"X-Generator: Launchpad (build 18610)\n"
#: SABnzbd.py [Error message]
msgid "MultiPar binary... NOT found!"
@@ -306,7 +306,7 @@ msgstr "Abgebrochen, unerwünschte Dateieindung gefunden"
#: sabnzbd/assembler.py [Warning message]
msgid "WARNING: Paused job \"%s\" because of rating (%s)"
msgstr "WARNUNG: Job \"%s\" aufgrund der Bewertung (%s) pausiert."
msgstr "WARNUNG: Aufgabe \"%s\" aufgrund der Bewertung (%s) pausiert."
#: sabnzbd/assembler.py [Warning message]
msgid "WARNING: Aborted job \"%s\" because of rating (%s)"
@@ -650,7 +650,7 @@ msgstr "Server-Adresse \"%s:%s\" ist ungültig."
#: sabnzbd/interface.py
msgid "Refused connection with hostname \"%s\" from:"
msgstr ""
msgstr "Verbindung vom Host \"%s\" abgelehnt von:"
#: sabnzbd/interface.py
msgid "User logged in to the web interface"
@@ -774,6 +774,8 @@ msgstr "Fehlerhafter Parameter"
msgid ""
"Category folder cannot be a subfolder of the Temporary Download Folder."
msgstr ""
"Der Category-Ordner darf kein Unterordner des Temporärer Download-Ordners "
"sein."
#: sabnzbd/interface.py # sabnzbd/interface.py
msgid "Back"
@@ -2539,6 +2541,9 @@ msgid ""
"Disconnect all active connections to usenet servers. Connections will be "
"reopened after a few seconds if there are items in the queue."
msgstr ""
"Alle aktiven Verbindungen zu Usenet-Servern trennen. Verbindungen werden "
"nach ein paar Sekunden wiederhergestellt, falls sich noch Artikel in der "
"Warteschlange befinden."
#: sabnzbd/skintext.py
msgid "This will send a test email to your account."
@@ -3287,7 +3292,8 @@ msgstr "Aktion wenn eine verschlüsselte RAR Datei geladen wird"
msgid ""
"In case of \"Pause\", you'll need to set a password and resume the job."
msgstr ""
"Im Fall von \"Pause\" müssen Sie ein Kennwort setzen und den Job fortsetzen."
"Im Fall von \"Pause\" müssen Sie ein Kennwort setzen und den Aufgabe "
"fortsetzen."
#: sabnzbd/skintext.py
msgid "Detect Duplicate Downloads"
@@ -3437,7 +3443,7 @@ msgstr "IONice-Parameter"
#: sabnzbd/skintext.py
msgid "External process priority"
msgstr ""
msgstr "Priorität von externem Prozess"
#: sabnzbd/skintext.py
msgid "Disconnect on Empty Queue"
@@ -4108,7 +4114,7 @@ msgstr "Geräte, welche die Nachrichten empfangen sollen"
#: sabnzbd/skintext.py [Pushover settings]
msgid "Emergency retry"
msgstr ""
msgstr "Notfall Wiederanlauf"
#: sabnzbd/skintext.py [Pushover settings]
msgid "How often (in seconds) the same notification will be sent"
@@ -4116,11 +4122,12 @@ msgstr "Wie oft die selbe benachrichtigung (in Sekunden) geschickt wird."
#: sabnzbd/skintext.py [Pushover settings]
msgid "Emergency expire"
msgstr ""
msgstr "Notfall Verfall"
#: sabnzbd/skintext.py [Pushover settings]
msgid "How many seconds your notification will continue to be retried"
msgstr ""
"Wieviele Sekunden soll versucht werden deine Nachricht erneut zu versenden"
#: sabnzbd/skintext.py [Header for Pushbullet notification section]
msgid "Pushbullet"
@@ -4277,7 +4284,7 @@ msgstr "S01E05 Episoden-Ordner"
#: sabnzbd/skintext.py
msgid "Job Name as Filename"
msgstr ""
msgstr "Aufgabe Name als Ordnername"
#: sabnzbd/skintext.py
msgid "Title"
@@ -4349,7 +4356,7 @@ msgstr "Ursprünglicher Dateiname"
#: sabnzbd/skintext.py
msgid "Original Job Name"
msgstr ""
msgstr "Ursprünglicher Aufgabe Name"
#: sabnzbd/skintext.py
msgid "Lower Case"
@@ -4721,6 +4728,8 @@ msgid ""
"All usernames, passwords and API-keys are automatically removed from the log "
"and the included copy of your settings."
msgstr ""
"Alle Benutzernamen, Passwörter und API-Schlüssel werden automatisch aus dem "
"Log und der darin enthaltenen Kopie deiner Einstellungen entfernt."
#: sabnzbd/skintext.py
msgid "Sort by Age <small>Oldest&rarr;Newest</small>"

View File

@@ -26,7 +26,7 @@ from sabnzbd.constants import DEF_HOST, DEF_PORT, DEF_STDINTF, DEF_ADMIN_DIR, \
from sabnzbd.config import OptionBool, OptionNumber, OptionPassword, \
OptionDir, OptionStr, OptionList, no_nonsense, \
validate_octal, validate_safedir, \
validate_octal, validate_safedir, all_lowercase, \
create_api_key, validate_notempty
##############################################################################
@@ -280,7 +280,7 @@ wait_ext_drive = OptionNumber('misc', 'wait_ext_drive', 5, 1, 60)
marker_file = OptionStr('misc', 'nomedia_marker', '')
ipv6_servers = OptionNumber('misc', 'ipv6_servers', 1, 0, 2)
url_base = OptionStr('misc', 'url_base', '/sabnzbd')
host_whitelist = OptionList('misc', 'host_whitelist')
host_whitelist = OptionList('misc', 'host_whitelist', validation=all_lowercase)
max_url_retries = OptionNumber('misc', 'max_url_retries', 10, 1)
##############################################################################

View File

@@ -1054,6 +1054,14 @@ def no_nonsense(value):
return None, value
def all_lowercase(value):
""" Lowercase everything! """
if isinstance(value, list):
# If list, for each item
return None, [item.lower() for item in value]
return None, value.lower()
def validate_octal(value):
""" Check if string is valid octal number """
if not value:

View File

@@ -51,7 +51,7 @@ RENAMES_FILE = '__renames__'
ATTRIB_FILE = 'SABnzbd_attrib'
REPAIR_REQUEST = 'repair-all.sab'
SABYENC_VERSION_REQUIRED = '3.3.4'
SABYENC_VERSION_REQUIRED = '3.3.5'
DB_HISTORY_VERSION = 1
DB_HISTORY_NAME = 'history%s.db' % DB_HISTORY_VERSION

View File

@@ -174,6 +174,11 @@ def check_hostname():
if host in cfg.host_whitelist():
return True
# Fine if ends with ".local" or ".local.", aka mDNS name
# See rfc6762 Multicast DNS
if host.endswith(('.local', '.local.')):
return True
# Ohoh, bad
log_warning_and_ip(T('Refused connection with hostname "%s" from:') % host)
return False

View File

@@ -65,14 +65,14 @@ else:
from subprocess import Popen
# Regex globals
RAR_RE = re.compile(r'\.(?P<ext>part\d*\.rar|rar|r\d\d|s\d\d|t\d\d|u\d\d|v\d\d|\d\d\d)$', re.I)
RAR_RE = re.compile(r'\.(?P<ext>part\d*\.rar|rar|r\d\d|s\d\d|t\d\d|u\d\d|v\d\d|\d\d\d?\d)$', re.I)
RAR_RE_V3 = re.compile(r'\.(?P<ext>part\d*)$', re.I)
LOADING_RE = re.compile(r'^Loading "(.+)"')
TARGET_RE = re.compile(r'^(?:File|Target): "(.+)" -')
EXTRACTFROM_RE = re.compile(r'^Extracting\sfrom\s(.+)')
EXTRACTED_RE = re.compile(r'^(Extracting|Creating|...)\s+(.*?)\s+OK\s*$')
SPLITFILE_RE = re.compile(r'\.(\d\d\d$)', re.I)
SPLITFILE_RE = re.compile(r'\.(\d\d\d?\d$)', re.I)
ZIP_RE = re.compile(r'\.(zip$)', re.I)
SEVENZIP_RE = re.compile(r'\.7z$', re.I)
SEVENMULTI_RE = re.compile(r'\.7z\.\d+$', re.I)

View File

@@ -189,6 +189,7 @@ class URLGrabber(Thread):
if item in _RARTING_FIELDS:
nzo_info[item] = value
# Get filename from Content-Disposition header
if not filename and "filename=" in value:
filename = value[value.index("filename=") + 9:].strip(';').strip('"')
@@ -209,7 +210,12 @@ class URLGrabber(Thread):
continue
if not filename:
filename = os.path.basename(url)
filename = os.path.basename(urllib2.unquote(url))
# URL was redirected, maybe the redirect has better filename?
# Check if the original URL has extension
if url != fetch_request.url and misc.get_ext(filename) not in VALID_NZB_FILES:
filename = os.path.basename(urllib2.unquote(fetch_request.url))
elif '&nzbname=' in filename:
# Sometimes the filename contains the full URL, duh!
filename = filename[filename.find('&nzbname=') + 9:]
@@ -361,13 +367,6 @@ def _analyse(fetch_request, url, future_nzo):
logging.debug('No usable response from indexer, retry after %s sec', when)
return None, msg, True, when, data
# Check for an error response
if not fetch_request or fetch_request.msg != 'OK':
# Increasing wait-time in steps for standard errors
when = DEF_TIMEOUT * (future_nzo.url_tries + 1)
logging.debug('Received nothing from indexer, retry after %s sec', when)
return None, fetch_request.msg, True, when, data
return fetch_request, fetch_request.msg, False, 0, data

View File

@@ -119,8 +119,12 @@ def test_nntp_server(host, port, server=None, username=None, password=None, ssl=
nw.clear_data()
nw.recv_chunk(block=True)
except:
# Some internal error, not always safe to close connection
return False, unicode(sys.exc_info()[1])
# Close the connection
nw.terminate(quit=True)
if nw.status_code == '480':
return False, T('Server requires username and password.')
@@ -136,5 +140,3 @@ def test_nntp_server(host, port, server=None, username=None, password=None, ssl=
else:
return False, T('Could not determine connection result (%s)') % nntp_to_msg(nw.data)
# Close the connection
nw.terminate(quit=True)

View File

@@ -50,7 +50,7 @@ class MailSlot(object):
def connect(self):
""" Connect to existing Mailslot so that writing is possible """
slot = r'\\%s\%s' % (os.environ['COMPUTERNAME'], MailSlot.slotname)
slot = r'\\.\%s' % MailSlot.slotname
self.handle = CreateFile(slot, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
return self.handle != -1