Compare commits

...

69 Commits

Author SHA1 Message Date
shypike
b396014f8d Fix IP test at startup.
Correction of problem introduced by commit afff88b "Use self-test.sabnzbd.org for connection tests".
2016-02-24 22:30:02 +01:00
shypike
1db32415b6 Update translations 2016-02-24 21:37:22 +01:00
shypike
b24629db6b Update text files for 1.0.0RC2 2016-02-24 21:11:43 +01:00
Safihre
9b5cdcf8fb Add trailing "/" to href's 2016-02-24 21:05:12 +01:00
shypike
4831415d14 Use self-test.sabnzbd.org for connection tests 2016-02-24 20:34:04 +01:00
Chris Thorn
a4c51f0b20 Parse bandwidth limit as a float instead of an integer so that non-integer values can be used as bandwidth limit 2016-02-24 20:09:02 +01:00
shypike
ec3ba1fb93 Changing server priorities during a download could lead to unexpected results and lockups.
Target priority of articles must be kept at the TryList level so that they
are reset when the try_list is reset.
Closes #378
2016-02-24 20:08:51 +01:00
Safihre
61966f7036 Plush dashboard local IPv4 wouldn't show if external failed
Typo!
For 1.0.0
2016-02-24 20:08:38 +01:00
Safihre
4f69e81841 Add link to information about SSL/yEnc 2016-02-24 20:07:48 +01:00
Safihre
d0d90581df Tweak first Config page 2016-02-24 20:07:35 +01:00
Safihre
8ea5c27633 Improve display of message on blocked server 2016-02-24 20:07:16 +01:00
shypike
517500fdf3 Add link to issue list on support site. 2016-02-19 22:42:30 +01:00
shypike
c4c1c9b6ab Prevent UI errors due to history_db handle not being available. 2016-02-19 22:22:42 +01:00
Safihre
2388889ede Filegrabber did not sanatize filename 2016-02-19 22:21:28 +01:00
Safihre
55cfe878d7 Catch failing Windows Notification
I assumed Windows notifications could not fail, but clearly they can:
http://forums.sabnzbd.org/viewtopic.php?f=11&t=20211&p=104438
When no tray-icon is available, it will fail and in the case of
completed NZB message it will restart the whole of SABnzbd.
2016-02-17 21:25:42 +01:00
Safihre
a2daaee468 Add Pystone score to Glitter status 2016-02-17 21:06:43 +01:00
Safihre
2c360e395e Limit to max 250 items per page (realistic limit) 2016-02-17 21:05:55 +01:00
Jonathon Saine
399cfee594 Add pyOpenSSL info to startup/utility/config base. Add OpenSSL & yEnc to config base as well. 2016-02-17 21:04:13 +01:00
shypike
be646ae6ab Set default for https verification to off. 2016-02-17 20:50:24 +01:00
shypike
b470253d9f Disable https verification when uploading NZB to running instance of SABnzbd. 2016-02-13 16:12:04 +01:00
shypike
b83c493492 Update translations 2016-02-11 01:06:52 +01:00
Safihre
991277bb01 Glitter broke on empty preload strings
See
http://forums.sabnzbd.org/viewtopic.php?f=11&t=20192&p=104368#p104368
In case of UnicodeError
2016-02-10 22:59:11 +01:00
Safihre
5626013b81 Don't allow name change or filesview on grabbing 2016-02-10 22:58:56 +01:00
Safihre
2810d37758 Make disabled servers look more disabled 2016-02-10 22:58:40 +01:00
Safihre
c2f08f01e0 #408 Show red when Add-NZB left empty 2016-02-10 22:57:30 +01:00
Safihre
17ff087e06 Do not confirm clearing warnings 2016-02-05 23:36:47 +01:00
Safihre
77de565b7c Link in message about Orphans was broken 2016-02-05 23:36:36 +01:00
Safihre
54d238aa4d Message labels were not translated
INFO and WARNING
2016-02-05 23:36:23 +01:00
Safihre
379d09f8cc Improve message about no localStorage
It happens more than I expected, so better make a proper message.
2016-02-05 23:35:23 +01:00
shypike
00de72b127 Update text files for 1.0.xRC1 2016-02-03 21:18:42 +01:00
shypike
f9c84fa7dd Fix trouble with disk speed meter (especially on Windows) Part 2.
Improve the benchmark by reducing Python overhead by writing larger blocks.
2016-02-03 21:08:47 +01:00
shypike
c8e46691bb Solve file name encoding issues for OSX.
- Names returned by unrar-commandline need to be Unicoded.
- For yEnc embedded names, only test for UTF-8 and CP1252, but not the local codepage.
- Suppress some bogus warnings
- Log the output of the unrar tool
2016-02-03 20:59:12 +01:00
shypike
df1bb636e5 Fix links in text files to pooit to 1.0.0 entries in the Wiki. 2016-02-03 20:51:19 +01:00
shypike
ff886fad0d Fix all links in the templates to point to 1.0.0 (or 1-0) entries in the Wiki. 2016-02-03 20:50:13 +01:00
shypike
6dbee7a413 Fix trouble with disk speed meter (especially on Windows) Part 2.
Move fix outside of the measurement loop.
Don't remove the test-file within the loop, but only after it's finished,
otherwise we'll still get a "Permission denied".
2016-01-30 10:52:28 +01:00
shypike
3f8fcd7172 Fix trouble with disk speed meter (especially on Windows).
Better handling when folder is not available or writable.
Windows requires some access outside of the Python code to avoid "permission denied".
2016-01-29 23:54:32 +01:00
shypike
d94f7388e6 Add a link on the main Config page, to the "issues" page on the Wiki 2016-01-29 19:55:04 +01:00
Safihre
ad8b49fea8 #408 Firefox-fix: word-wrap instead of word-break 2016-01-29 19:21:59 +01:00
Safihre
ce00270c12 #447 only show arguments-field for speedlimit 2016-01-29 19:21:41 +01:00
Safihre
8c501f8f58 #447 Servers in scheduler more clear 2016-01-29 19:21:30 +01:00
Safihre
ce313ebc65 #445 Reduce statusinfo timeout on startup 2016-01-29 19:21:18 +01:00
Safihre
887ad881a2 #444 HTTPS instead of HTTP for RSS favicon 2016-01-29 19:21:07 +01:00
Safihre
ce40827552 Fix breaking RSS page
Fixes http://forums.sabnzbd.org/viewtopic.php?f=11&t=20114
2016-01-29 19:20:52 +01:00
shypike
2777d89482 Fix typos that prevented notifications about disk full being sent. 2016-01-28 23:19:36 +01:00
shypike
727b300a0e Update translations 2016-01-24 16:34:40 +01:00
shypike
652b021a8e Update text files for 0.8.0Beta6 2016-01-24 16:26:26 +01:00
shypike
fdf33acfbb Allow "None" as selection for secondary skin. 2016-01-24 16:15:02 +01:00
shypike
b001bc9b6f Prevent multiple resume notifications.
Only report "Resume" when coming from Paused mode.
2016-01-24 15:18:24 +01:00
shypike
8802cb1d8c Notifications template contained two instances of "ncenter_enable", leading to problems.
The result was a list instead of a single value.
2016-01-24 15:18:07 +01:00
shypike
e19a2fbae7 Improve handling of an old queue when upgrading to 0.8.0+
Warn only for a non-empty queue.
For Windows, when using a relative "download_dir" based on the user profile,
prepend the path with "Documents".
No action when the -f parameter was used.
This way it will be easier to restore existing jobs.
2016-01-24 15:17:47 +01:00
Safihre
53e38f98f9 Firefox needs more time to process the Server AJAX 2016-01-24 15:16:52 +01:00
Safihre
e783e227f6 #438 Try to stop Firefox from checking checkboxes 2016-01-24 15:16:39 +01:00
shypike
f3dfbe4181 Fix problem where a stray RAR file would cause a failed unpack run.
When a job of which the RAR files are renamed by par2,
needs repair of one more more files, the original damaged files will stay behind.
This will cause SABnzbd to try a doomed attempt at unpacking.
SABnzbd should keep track of such files and delete them after repair.
2016-01-24 15:15:57 +01:00
shypike
bcd8ca8bc4 Fix potential crash when reverting par2 renames.
Can happen when files have been modified outside of SABnzbd's control.
2016-01-24 15:12:06 +01:00
shypike
816d6a63cd For SSL protocol choice, default to auto-negotiation.
The "V23" method is interpreted by OpenSSL as "negotiate the highest available protocol"
and should therefor be a safe choice (best chance of working and best security).
If a user wants to, it is possible to fix the protocol, to prevent interference in the negotiation.
We cannot just assume that we can use our highest fixed protocol, because some Usenet servers
are being slow with implementing TLS1.2
2016-01-24 15:11:30 +01:00
shypike
88d3f25700 Perform IPv6 test on port 443 instead of 80.
Works better with some proxies.
Closes issue #274
2016-01-19 18:13:42 +01:00
shypike
80f69b11db When trying to connect to another SABnzbd instance over HTTPS, don't verify certificates.
Very few SABnzbd installations will have valid certificates.
2016-01-19 18:03:33 +01:00
Safihre
81a11f20c8 Re-order Switches page 2016-01-19 17:30:01 +01:00
Safihre
9e2a839953 Config fixes 2016-01-19 17:30:01 +01:00
Safihre
3cefcde270 #408 Refresh on Config Special save to update the * 2016-01-19 17:30:01 +01:00
Safihre
87a1eacfe7 #408 Also close history-details on history-row click
Before it would only open
2016-01-19 17:30:01 +01:00
Safihre
7cbc1a8419 #408 Browser navbar to black on mobile 2016-01-19 17:30:01 +01:00
Safihre
7b5570eb0b #408 Extra space next to Folder icon 2016-01-19 17:30:00 +01:00
Safihre
1a43a4dcf0 #432 Change filename to name in Add NZB 2016-01-19 17:30:00 +01:00
Safihre
2c2a6592c7 End of queue script was forgotten in Glitter 2016-01-19 17:30:00 +01:00
shypike
f31de6ee4e The compiled OSX build wasn't restarted with original command line arguments.
Rare use case where the App was originally started with parameters.
Essential for correct preservation of the -f parameter.
2016-01-19 17:29:11 +01:00
shypike
8fcd1f6b6c Merge branch 'develop' into R0.8.0 2016-01-16 12:25:38 +01:00
shypike
d7f3a473d7 Merge branch 'develop' into R0.8.0 2016-01-13 21:51:51 +01:00
shypike
ab2eb0c94e Update text files for 0.8.0Beta5 2016-01-13 20:17:32 +01:00
60 changed files with 13972 additions and 12974 deletions

View File

@@ -1,5 +1,5 @@
*******************************************
*** This is SABnzbd 0.8.0 ***
*** This is SABnzbd 1.0.0 ***
*******************************************
SABnzbd is an open-source cross-platform binary newsreader.
It simplifies the process of downloading from Usenet dramatically,
@@ -12,8 +12,8 @@ and offers a complete API for third-party applications to hook into.
There is an extensive Wiki on the use of SABnzbd.
http://wiki.sabnzbd.org/
IMPORTANT INFORMATION about release 0.8.0:
http://wiki.sabnzbd.org/introducing-0-8-0
IMPORTANT INFORMATION about release 1.0.0:
http://wiki.sabnzbd.org/introducing-1-0-0
Please also read the file "ISSUES.txt"
@@ -37,6 +37,6 @@ Install new version
Start SABnzbd.
The organization of the download queue is different from 0.7.x (and older).
0.8.0 will not finish downloading an existing queue.
1.0.0 will not finish downloading an existing queue.
Also, your sabnzbd.ini file will be upgraded, making it
incompatible with older releases.

View File

@@ -1,4 +1,4 @@
SABnzbd 0.8.0
SABnzbd 1.0.0
-------------------------------------------------------------------------------
0) LICENSE

View File

@@ -24,13 +24,13 @@
For these the server blocking method is not very favourable.
There is an INI-only option that will limit blocks to 1 minute.
no_penalties = 1
See: http://wiki.sabnzbd.org/configure-special-0-8
See: http://wiki.sabnzbd.org/configure-special-1-0
- Some third-party utilties try to probe SABnzbd API in such a way that you will
often see warnings about unauthenticated access.
If you are sure these probes are harmless, you can suppress the warnings by
setting the option "api_warnings" to 0.
See: http://wiki.sabnzbd.org/configure-special-0-8
See: http://wiki.sabnzbd.org/configure-special-1-0
- On OSX you may encounter downloaded files with foreign characters.
The par2 repair may fail when the files were created on a Windows system.
@@ -41,7 +41,7 @@
You will see this only when downloaded files contain accented characters.
You need to fix it yourself by running the convmv utility (available for most Linux platforms).
Possible the file system override setting 'fsys_type' might be solve things:
See: http://wiki.sabnzbd.org/configure-special-0-8
See: http://wiki.sabnzbd.org/configure-special-1-0
- The "Watched Folder" sometimes fails to delete the NZB files it has
processed. This happens when other software still accesses these files.
@@ -81,4 +81,4 @@
- Squeeze Linux
There is a "special" option that will allow you to select an alternative library.
use_pickle = 1
See: http://wiki.sabnzbd.org/configure-special-0-8
See: http://wiki.sabnzbd.org/configure-special-1-0

View File

@@ -1,7 +1,7 @@
Metadata-Version: 1.0
Name: SABnzbd
Version: 0.8.0Beta4
Summary: SABnzbd-0.8.0Beta4
Version: 1.0.0RC2
Summary: SABnzbd-1.0.0RC2
Home-page: http://sabnzbd.org
Author: The SABnzbd Team
Author-email: team@sabnzbd.org

View File

@@ -1,5 +1,33 @@
Release Notes - SABnzbd 0.8.0Beta4
====================================
Release Notes - SABnzbd 1.0.0RC2
==================================
## Changes in RC2
- Changing server priorities during a download could lead to unexpected results and lockups
- Made Glitter friendly for reverse proxies
- Config->General shows more diagnostic info
- Default host to test IPv6 is now self-test.sabnzbd.org
## Changes in RC1
- Bump version from 0.8.0RC1 to 1.0.0RC1
- Fixed "disk-full" notification
- Glitter: several small problems fixed
- OSX: fixed error message that comes when job with accented characters completes
- Fixed diskspeed meter (in Glitter)
## Changes in Beta6
- Fixed issues in Config->Server (Firefox)
- Fixed queue upgrade warning for Windows
- SSL protocol by default auto-negotiated with server
- Fixed problem of multiple instances of SABnzbd when starting it with an NZB
- Fix problem of stray RAR files after unpack, which would fail the job
- Lots of Glitter tweaks and fixes
## Changes in Beta5
- Glitter improvements
- Faster initial loading of Glitter on Firefox and Chrome
- Support extra parameters for par2 on other platforms than Windows
- Proper sorting of download report
- Several fixes for rare problems
## Changes in Beta4
- Unicode crashes in user interface fixed
@@ -53,7 +81,7 @@ Release Notes - SABnzbd 0.8.0Beta4
- Diagnostic dashboard tab for "Status" page
## What's new in 0.8.0
## What's new in 1.0.0
- Full Unicode support with Chinese and Russian translations
- Improved Notifications (including Prowl)
@@ -77,8 +105,8 @@ Release Notes - SABnzbd 0.8.0Beta4
(c) Copyright 2007-2016 by "The SABnzbd-team" \<team@sabnzbd.org\>
### IMPORTANT INFORMATION about release 0.8.0
<http://wiki.sabnzbd.org/introducing-0-8-0>
### IMPORTANT INFORMATION about release 1.0.0
<http://wiki.sabnzbd.org/introducing-1-0-0>
### Known problems and solutions
- Read the file "ISSUES.txt"
@@ -90,7 +118,7 @@ Release Notes - SABnzbd 0.8.0Beta4
- Start SABnzbd
The organization of the download queue is different from older versions.
0.8.x will not see the existing queue, but you can go to
1.0.x will not see the existing queue, but you can go to
Status->QueueRepair and "Repair" the old queue.
Also, your sabnzbd.ini file will be upgraded, making it
incompatible with releases older than 0.7.9

View File

@@ -714,7 +714,10 @@ def is_sabnzbd_running(url, timeout=None):
""" Return True when there's already a SABnzbd instance running. """
try:
url = '%s&mode=version' % (url)
# Do this without certificate verification, few installations will have that
prev = sabnzbd.set_https_verification(False)
ver = sabnzbd.newsunpack.get_from_url(url, timeout=timeout)
sabnzbd.set_https_verification(prev)
return bool(ver and re.search(r'\d+\.\d+\.', ver))
except:
return False
@@ -743,8 +746,10 @@ def check_for_sabnzbd(url, upload_nzbs, allow_browser=True):
# Upload any specified nzb files to the running instance
if upload_nzbs:
from sabnzbd.utils.upload import upload_file
prev = sabnzbd.set_https_verification(0)
for f in upload_nzbs:
upload_file(url, f)
sabnzbd.set_https_verification(prev)
else:
# Launch the web browser and quit since sabnzbd is already running
# Trim away everything after the final slash in the URL
@@ -1237,6 +1242,7 @@ def main():
logging.info('--------------------------------')
logging.info('%s-%s (rev=%s)', sabnzbd.MY_NAME, sabnzbd.__version__, sabnzbd.__baseline__)
logging.info('Full executable path = %s', sabnzbd.MY_FULLNAME)
if sabnzbd.WIN32:
suffix = ''
if vista_plus:
@@ -1253,7 +1259,7 @@ def main():
logging.info('Arguments = %s', sabnzbd.CMDLINE)
if sabnzbd.cfg.log_level() > 1:
from sabnzbd.utils.getipaddress import localipv4, publicipv4, ipv6
from sabnzbd.getipaddress import localipv4, publicipv4, ipv6
mylocalipv4 = localipv4()
if mylocalipv4:
@@ -1359,6 +1365,7 @@ def main():
import sabnzbd.utils.sslinfo
logging.info("SSL version %s", sabnzbd.utils.sslinfo.ssl_version())
logging.info("pyOpenSSL version %s", sabnzbd.utils.sslinfo.pyopenssl_version())
logging.info("SSL potentially supported protocols %s", str(sabnzbd.utils.sslinfo.ssl_potential()))
logging.info("SSL actually supported protocols %s", str(sabnzbd.utils.sslinfo.ssl_protocols()))
@@ -1671,16 +1678,20 @@ def main():
sys.argv = re_argv
os.chdir(org_dir)
if sabnzbd.DARWIN:
args = sys.argv[:]
args.insert(0, sys.executable)
# TODO: when executing from sources on osx, after a restart, process is detached from console
# If OSX frozen restart of app instead of embedded python
if getattr(sys, 'frozen', None) == 'macosx_app':
# [[NSProcessInfo processInfo] processIdentifier]]
# logging.info("%s" % (NSProcessInfo.processInfo().processIdentifier()))
logging.info(os.getpid())
os.system('kill -9 %s && open "%s"' % (os.getpid(), sabnzbd.MY_FULLNAME.replace("/Contents/MacOS/SABnzbd", "")))
my_pid = os.getpid()
my_name = sabnzbd.MY_FULLNAME.replace('/Contents/MacOS/SABnzbd', '')
my_args = ' '.join(sys.argv[1:])
cmd = 'kill -9 %s && open "%s" --args %s' % (my_pid, my_name, my_args)
logging.info('Launching: ', cmd)
os.system(cmd)
else:
args = sys.argv[:]
args.insert(0, sys.executable)
pid = os.fork()
if pid == 0:
os.execv(sys.executable, args)

View File

@@ -1,60 +1,117 @@
<!--#set global $pane="Config"#-->
<!--#set global $help_uri="configure-0-7"#-->
<!--#set global $help_uri="configure-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<div class="section padTable">
<table id="infoTable">
<tbody>
<tr class="alt">
<td class="infoTableHeader">$T('version'): </td>
<td class="infoTableCell">$version [$build]</td>
</tr>
<tr>
<td class="infoTableHeader">$T('uptime'): </td>
<td class="infoTableCell">$uptime</td>
</tr>
<tr class="alt">
<td class="infoTableHeader">$T('confgFile'): </td>
<td class="infoTableCell">$configfn</td>
</tr>
<tr>
<td class="infoTableHeader">$T('cache').capitalize(): </td>
<td class="infoTableCell"><!--#set $msg=$T('ft-buffer@2')%($cache_art, $cache_size)#-->$msg</td>
</tr>
<tr class="alt">
<td class="infoTableHeader">$T('parameters'): </td>
<td class="infoTableCell">$cmdline</td>
</tr>
<tr>
<td class="infoTableHeader">$T('pythonVersion'): </td>
<td class="infoTableCell">$sys.version[:120]</td>
</tr>
<tr class="infoTableSeperator alt">
<td class="infoTableHeader">$T('homePage') </td>
<td class="infoTableCell"><a href="http://sabnzbd.org/" target="_blank">http://sabnzbd.org/</a></td>
</tr>
<tr>
<td class="infoTableHeader">$T('menu-wiki') </td>
<td class="infoTableCell"><a href="http://wiki.sabnzbd.org/faq" target="_blank">http://wiki.sabnzbd.org/faq</a></td>
</tr>
<tr class="alt">
<td class="infoTableHeader">$T('menu-forums') </td>
<td class="infoTableCell"><a href="http://forums.sabnzbd.org/" target="_blank">http://forums.sabnzbd.org/</a></td>
</tr>
<tr>
<td class="infoTableHeader">$T('source') </td>
<td class="infoTableCell"><a href="https://github.com/sabnzbd/sabnzbd" target="_blank">https://github.com/sabnzbd/sabnzbd</a></td>
</tr>
<tr class="alt">
<td class="infoTableHeader">$T('menu-irc') </td>
<td class="infoTableCell"><a href="irc://irc.synirc.net/#sabnzbd"><i>#sabnzbd</i> on <i>irc.synirc.net</i></a> $T('or') (<a href="http://sabnzbd.org/live-chat/" target="_blank">webchat</a>)</td>
</tr>
</tbody>
</table>
<!--#from sabnzbd.newswrapper import HAVE_SSL#-->
<!--#import sabnzbd.utils.sslinfo#-->
<!--#from sabnzbd.decoder import HAVE_YENC#-->
<!--#from sabnzbd.newsunpack import PAR2_COMMAND, PAR2C_COMMAND, RAR_COMMAND, ZIP_COMMAND, SEVEN_COMMAND, NICE_COMMAND, IONICE_COMMAND#-->
<div class="colmask">
<div class="section padTable">
<table class="table table-striped">
<tbody>
<tr>
<th scope="row">$T('version'): </th>
<td>$version [$build]</td>
</tr>
<tr>
<th scope="row">$T('uptime'): </th>
<td>$uptime</td>
</tr>
<tr>
<th scope="row">$T('confgFile'): </th>
<td>$configfn</td>
</tr>
<tr>
<th scope="row">$T('cache').capitalize(): </th>
<td><!--#set $msg=$T('ft-buffer@2')%($cache_art, $cache_size)#-->$msg</td>
</tr>
<tr>
<th scope="row">$T('parameters'): </th>
<td>$cmdline</td>
</tr>
<tr>
<th scope="row">$T('pythonVersion'): </th>
<td>$sys.version[:120]</td>
</tr>
<tr>
<th scope="row">OpenSSL:</th>
<td>
<!--#if HAVE_SSL#-->
<!--#set $sslversions = ', '.join(sabnzbd.utils.sslinfo.ssl_protocols())#-->
$sabnzbd.utils.sslinfo.ssl_version() <em>[$sslversions]</em>
<!--#else#-->
<span class="label label-warning">$T('notAvailable')</span>
<a href="$helpuri$help_uri#no_ssl" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
<!--#end if#-->
</td>
</tr>
<tr>
<th scope="row">pyOpenSSL:</th>
<td>
<!--#if HAVE_SSL#-->
$sabnzbd.utils.sslinfo.pyopenssl_version()
<!--#else#-->
<span class="label label-warning">$T('notAvailable')</span>
<a href="$helpuri$help_uri#no_ssl" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
<!--#end if#-->
</td>
</tr>
<tr>
<th scope="row">yEnc:</th>
<td>
<!--#if HAVE_YENC#-->
<span class="glyphicon glyphicon-ok"></span>
<!--#else#-->
<span class="label label-warning">$T('notAvailable')</span>
<a href="$helpuri$help_uri#no_yenc" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
<!--#end if#-->
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="padding alt">
<h5 class="copyright">Copyright &copy; 2008-2016 The SABnzbd Team &lt;<a href="mailto:team@sabnzbd.org">team@sabnzbd.org</a>&gt;</h5>
<p class="copyright"><small>$T('yourRights')</small></p>
<div class="colmask">
<div class="section padTable">
<table class="table table-striped">
<tbody>
<tr>
<th scope="row">$T('homePage') </th>
<td><a href="http://sabnzbd.org/" target="_blank">http://sabnzbd.org/</a></td>
</tr>
<tr>
<th scope="row">$T('menu-wiki') </th>
<td><a href="http://wiki.sabnzbd.org/faq" target="_blank">http://wiki.sabnzbd.org/faq</a></td>
</tr>
<tr>
<th scope="row">$T('menu-forums') </th>
<td><a href="http://forums.sabnzbd.org/" target="_blank">http://forums.sabnzbd.org/</a></td>
</tr>
<tr>
<th scope="row">$T('source') </th>
<td><a href="https://github.com/sabnzbd/sabnzbd" target="_blank">https://github.com/sabnzbd/sabnzbd</a></td>
</tr>
<tr>
<th scope="row">$T('menu-irc') </th>
<td><a href="irc://irc.synirc.net/#sabnzbd"><i>#sabnzbd</i> on <i>irc.synirc.net</i></a> $T('or') (<a href="http://sabnzbd.org/live-chat/" target="_blank">webchat</a>)</td>
</tr>
<tr>
<th scope="row">$T('menu-issues') </th>
<td><a href="http://wiki.sabnzbd.org/issues-1-0-0" target="_blank">http://wiki.sabnzbd.org/issues-1-0-0</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="colmask">
<div class="padding alt">
<h5 class="copyright">Copyright &copy; 2008-2016 The SABnzbd Team &lt;<a href="mailto:team@sabnzbd.org">team@sabnzbd.org</a>&gt;</h5>
<p class="copyright"><small>$T('yourRights')</small></p>
</div>
</div>
<!--#include $webdir + "/_inc_footer_uc.tmpl"#-->

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="Categories"#-->
<!--#set global $help_uri="configure-categories-0-7"#-->
<!--#set global $help_uri="configure-categories-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<div class="section">

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="Folders"#-->
<!--#set global $help_uri="configure-folders-0-7"#-->
<!--#set global $help_uri="configure-folders-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="General"#-->
<!--#set global $help_uri="configure-general-0-8"#-->
<!--#set global $help_uri="configure-general-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
@@ -49,6 +49,7 @@
<div class="field-pair">
<label class="config" for="web_dir2">$T('opt-web_dir2')</label>
<select name="web_dir2" id="web_dir2">
<option value="None" selected="selected">$T("None")</option>
<!--#for $webline in $web_list#-->
<!--#if $webline.lower() == $web_dir2.lower()#-->
<option value="$webline" selected="selected">$webline</option>

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="Email"#-->
<!--#set global $help_uri="configure-notifications-0-8"#-->
<!--#set global $help_uri="configure-notifications-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
@@ -82,11 +82,6 @@
</div><!-- /col2 -->
<div class="col1" <!--#if int($ncenter_enable) > 0 then '' else 'style="display:none"'#-->>
<fieldset>
<div class="field-pair">
<label class="config wide" for="ncenter_enable">$T('opt-ncenter_enable')</label>
<input type="checkbox" name="ncenter_enable" id="ncenter_enable" value="1" <!--#if int($ncenter_enable) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-ncenter_enable')</span>
</div>
<div class="field-pair">
<label class="config wide" for="ncenter_prio_startup">$T($notify_texts['startup']).replace('/', ' / ')</label>
<input type="checkbox" name="ncenter_prio_startup" id="ncenter_prio_startup" value="1" <!--#if int($ncenter_prio_startup) > 0 then 'checked="checked"' else ""#--> />

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="RSS"#-->
<!--#set global $help_uri="configure-rss-0-8"#-->
<!--#set global $help_uri="configure-rss-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<!--#if not $active_feed#-->
@@ -7,7 +7,7 @@
<div class="padTable">
<a class="main-helplink" href="$helpuri$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a>
<p>$T('explain-RSS')</p>
<form action="add_rss_feed" method="post" novalidate>
<form action="add_rss_feed" method="post" autocomplete="off" novalidate>
<input type="hidden" name="session" value="$session" />
<table class="catTable">
<tr>
@@ -37,7 +37,7 @@
<!--#if $rss#-->
<div class="section">
<div class="padTable">
<form action="save_rss_feed" method="post" novalidate>
<form action="save_rss_feed" method="post" autocomplete="off" novalidate>
<input type="hidden" name="session" value="$session" />
<table id="subscriptions">
<tbody>
@@ -51,7 +51,7 @@
</td>
<td class="title">
<a href="?feed=$rss[$feed_item]['link']" class="subscription-title path feed <!--#if int($rss[$feed_item]['enable']) != 0 then 'feed_enabled' else 'feed_disabled'#-->">
<div class="favicon" style="background-image: url(http://www.google.com/s2/favicons?domain=$rss[$feed_item]['baselink']&amp;alt=feed);"></div> $feed_item
<div class="favicon" style="background-image: url(https://www.google.com/s2/favicons?domain=$rss[$feed_item]['baselink']&amp;alt=feed);"></div> $feed_item
</a>
</td>
<td class="controls">
@@ -73,7 +73,7 @@
</form>
<!--#if $feeds#-->
<br/>
<form action="rss_now" method="post" novalidate>
<form action="rss_now" method="post" autocomplete="off" novalidate>
<input type="hidden" name="session" value="$session" />
<button type="submit" class="btn btn-default readAll"><span class="glyphicon glyphicon-sort"></span> $T('button-rssNow')</button>
</form>
@@ -82,7 +82,7 @@
</div>
<!--#end if#-->
<div class="section">
<form action="save_rss_rate" method="post">
<form action="save_rss_rate" method="post" autocomplete="off">
<input type="hidden" name="session" value="$session" />
<div class="col1">
<fieldset>
@@ -279,7 +279,7 @@
<!--#set $fnum = 0#-->
<!--#for $filter in $rss[$feed].filters#-->
<!--#set $odd = not $odd#-->
<form action="upd_rss_filter" method="post">
<form action="upd_rss_filter" method="post" autocomplete="off">
<input type="hidden" name="session" value="$session" />
<input type="hidden" name="index" value="$fnum" />
<input type="hidden" name="feed" value="$feed" />

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="Scheduling"#-->
<!--#set global $help_uri="configure-scheduling-0-8"#-->
<!--#set global $help_uri="configure-scheduling-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<%
@@ -17,7 +17,7 @@ else:
<div class="col2">
<h3>$T('addSchedule') <a href="$helpuri$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></h3>
</div><!-- /col2 -->
<form action="addSchedule" method="post">
<form action="addSchedule" method="post" autocomplete="off">
<input type="hidden" id="session" name="session" value="$session" />
<div class="col1">
<fieldset>
@@ -48,12 +48,20 @@ else:
<div class="field-pair">
<label class="config" for="action">$T('sch-action')</label>
<select name="action" id="action">
<!--#for $action in $actions#-->
<option value="$action">$actions_lng[$action]</option>
<!--#end for#-->
<optgroup label="$T('sch-action')">
<!--#for $action in $actions#-->
<option value="$action" data-action="" data-noarg="<!--#if $action is 'speedlimit' then 0 else 1#-->">$actions_lng[$action]</option>
<!--#end for#-->
</optgroup>
<optgroup label="$T('cmenu-servers')">
<!--#for $server in $actions_servers.keys()#-->
<option value="$server" data-action="1"data-noarg="1">$T('sch-enable_server') "$actions_servers[$server]"</option>
<option value="$server" data-action="0"data-noarg="1">$T('sch-disable_server') "$actions_servers[$server]"</option>
<!--#end for#-->
</optgroup>
</select>
</div>
<div class="field-pair">
<div class="field-pair" id="hidden_arguments" style="display: none">
<label class="config" for="arguments">$T('sch-arguments')</label>
<input type="text" name="arguments" id="arguments" class="select_width" />
</div>
@@ -97,5 +105,16 @@ else:
</div><!-- /col1 -->
</div><!-- /section -->
</div><!-- /colmask -->
<script type="text/javascript">
\$('#action').on('change', function() {
// Set the action
\$('#arguments').val((\$(this).find('option:selected').data('action')))
// Arguments
if(\$(this).find('option:selected').data('noarg')) {
\$('#hidden_arguments').hide()
} else {
\$('#hidden_arguments').show()
}
})
</script>
<!--#include $webdir + "/_inc_footer_uc.tmpl"#-->

View File

@@ -1,5 +1,5 @@
<!--#set global $pane="Servers"#-->
<!--#set global $help_uri="configure-servers-0-8"#-->
<!--#set global $help_uri="configure-servers-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
@@ -62,6 +62,7 @@
<label class="config" for="ssl_type">$T('srv-ssl_type')</label>
<!--#if int($have_ssl) == 1#-->
<select name="ssl_type" id="ssl_type">
<option value="">$T('Default')</option>
<!--#if 't12' in $ssl_protocols#-->
<option value="t12">TLS v1.2</option>
<!--#end if#-->
@@ -71,9 +72,6 @@
<!--#if 't1' in $ssl_protocols#-->
<option value="t1">TLS v1</option>
<!--#end if#-->
<!--#if 'v23' in $ssl_protocols#-->
<option value="v23">SSL v23</option>
<!--#end if#-->
<!--#if 'v3' in $ssl_protocols#-->
<option value="v3">SSL v3</option>
<!--#end if#-->
@@ -118,24 +116,25 @@
</fieldset>
</div><!-- /col1 -->
</div><!-- /section -->
</form>
</form>
<!--#set $cur = 0#-->
<!--#for $server in $servers#-->
<!--#set $cur = $cur + 1#-->
<form action="saveServer" method="post" class="fullform" novalidate>
<form action="saveServer" method="post" class="fullform" autocomplete="off" novalidate>
<input type="hidden" name="session" value="$session" />
<input type="hidden" name="server" value="$server['name']" />
<div class="section">
<div class="col2">
<div class="section <!--#if int($server['enable']) == 0 then 'server-disabled' else ""#-->">
<div class="col2 <!--#if int($server['enable']) == 0 then 'server-disabled' else ""#-->">
<h3>$server['displayname'] <a href="$helpuri$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></h3>
<span class="label label-primary" data-priority="$server['priority']">$server['priority']</span>
<span class="label label-primary" data-priority="$server['priority']">$T('srv-priority'):</span>
<!--#if int($server['enable']) != 0#-->
<span class="label label-primary" data-priority="$server['priority']#-->">$server['priority']</span>
<span class="label label-primary" data-priority="$server['priority']#-->">$T('srv-priority'):</span>
<!--#end if#-->
<table><tr>
<td><input type="checkbox" class="toggleServerCheckbox" id="enable_$cur" rel="$server['name']" name="q_enable" value="1" <!--#if int($server['enable']) != 0 then 'checked="checked"' else ""#--> /></td>
<td><input type="checkbox" class="toggleServerCheckbox" id="enable_$cur" name="$server['name']" value="1" <!--#if int($server['enable']) != 0 then 'checked="checked"' else ""#--> /></td>
<td><label for="enable_$cur">$T('enabled')</label></td>
</tr></table>
@@ -186,6 +185,7 @@
<label class="config" for="ssl_type$cur">$T('srv-ssl_type')</label>
<!--#if int($have_ssl) == 1#-->
<select name="ssl_type" id="ssl_type$cur">
<option value="" <!--#if $server['ssl_type'] == "" then 'selected="selected"' else ""#--> >$T('Default')</option>
<!--#if 't12' in $ssl_protocols#-->
<option value="t12" <!--#if $server['ssl_type'] == "t12" then 'selected="selected"' else ""#--> >TLS v1.2</option>
<!--#end if#-->
@@ -195,9 +195,6 @@
<!--#if 't1' in $ssl_protocols#-->
<option value="t1" <!--#if $server['ssl_type'] == "t1" then 'selected="selected"' else ""#--> >TLS v1</option>
<!--#end if#-->
<!--#if 'v23' in $ssl_protocols#-->
<option value="v23" <!--#if $server['ssl_type'] == "v23" then 'selected="selected"' else ""#--> >SSL v23</option>
<!--#end if#-->
<!--#if 'v3' in $ssl_protocols#-->
<option value="v3" <!--#if $server['ssl_type'] == "v3" then 'selected="selected"' else ""#--> >SSL v3</option>
<!--#end if#-->
@@ -285,15 +282,13 @@
\$(this).css('background-color', theColor)
})
/**
High-light disabled servers
**/
\$('.toggleServerCheckbox:not(:checked)').parents('.col2').addClass('server-disabled').find('.label').css('background-color', '#777')
/**
Click events
**/
\$('.showserver').click(function () {
if(\$(this).parent().hasClass('server-disabled')) {
\$(this).parent().parent().toggleClass('server-disabled')
}
\$(this).parent().next().toggle();
\$(this).parent().next().next().toggle();
if (\$(this).attr("value") == "$T('showDetails')") {
@@ -324,7 +319,7 @@
// Let us leave!
formWasSubmitted = true;
formHasChanged = false;
location.reload();
setTimeout(function() { location.reload(); }, 100)
}
return false;
});
@@ -334,12 +329,12 @@
// Let us leave!
formWasSubmitted = true;
formHasChanged = false;
location.reload();
setTimeout(function() { location.reload(); }, 100)
}
return false;
});
\$('.toggleServerCheckbox').click(function(){
var whichServer = \$(this).attr("rel");
var whichServer = \$(this).attr("name");
\$.ajax({
type: "POST",
url: "toggleServer",
@@ -348,7 +343,7 @@
// Let us leave!
formWasSubmitted = true;
formHasChanged = false;
location.reload();
setTimeout(function() { location.reload(); }, 100)
});
});
});

View File

@@ -1,9 +1,9 @@
<!--#set global $pane="Sorting"#-->
<!--#set global $help_uri="configure-sorting-0-7"#-->
<!--#set global $help_uri="configure-sorting-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<form action="saveSorting" method="post" name="fullform" class="fullform">
<form action="saveSorting" method="post" name="fullform" class="fullform" autocomplete="off">
<input type="hidden" id="session" name="session" value="$session" />
<input id="complete_dir" type="hidden" value="$complete_dir" />
<div class="section">

View File

@@ -1,9 +1,9 @@
<!--#set global $pane="Special"#-->
<!--#set global $help_uri="configure-special-0-8"#-->
<!--#set global $help_uri="configure-special-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<form action="saveSpecial" method="post" name="fullform" class="fullform">
<form action="saveSpecial" method="post" autocomplete="off">
<input type="hidden" id="session" name="session" value="$session" />
<div class="padTable">
<h4 class="darkred nomargin">$T('explain-special')</h4>

View File

@@ -1,9 +1,9 @@
<!--#set global $pane="Switches"#-->
<!--#set global $help_uri="configure-switches-0-8"#-->
<!--#set global $help_uri="configure-switches-1-0"#-->
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
<div class="colmask">
<form action="saveSwitches" method="post" name="fullform" class="fullform">
<form action="saveSwitches" method="post" name="fullform" class="fullform" autocomplete="off">
<input type="hidden" id="session" name="session" value="$session" />
<div class="section">
<div class="col2">
@@ -11,6 +11,11 @@
</div><!-- /col2 -->
<div class="col1">
<fieldset>
<div class="field-pair">
<label class="config" for="auto_browser">$T('opt-auto_browser')</label>
<input type="checkbox" name="auto_browser" id="auto_browser" value="1" <!--#if int($auto_browser) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-auto_browser')</span>
</div>
<div class="field-pair">
<label class="config" for="check_new_rel">$T('opt-check_new_rel')</label>
<select name="check_new_rel" id="check_new_rel">
@@ -20,11 +25,6 @@
</select>
<span class="desc">$T('explain-check_new_rel')</span>
</div>
<div class="field-pair">
<label class="config" for="auto_browser">$T('opt-auto_browser')</label>
<input type="checkbox" name="auto_browser" id="auto_browser" value="1" <!--#if int($auto_browser) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-auto_browser')</span>
</div>
<div class="field-pair <!--#if not $have_ampm then "disabled" else "" #-->">
<label class="config" for="ampm">$T('opt-ampm')</label>
<input type="checkbox" name="ampm" id="ampm" value="1" <!--#if int($ampm) > 0 then 'checked="checked"' else ""#--> <!--#if not $have_ampm then 'readonly="readonly" disabled="disabled"' else "" #--> />
@@ -79,15 +79,33 @@
<div class="col1">
<fieldset>
<div class="field-pair">
<label class="config" for="fail_hopeless">$T('opt-fail_hopeless')</label>
<input type="checkbox" name="fail_hopeless" id="fail_hopeless" value="1" <!--#if int($fail_hopeless) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-fail_hopeless')</span>
<label class="config" for="pre_script">$T('opt-pre_script')</label>
<select name="pre_script" id="pre_script">
<!--#for $sc in $script_list#-->
<!--#if $sc.lower() == $pre_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-pre_script')</span>
</div>
<div class="field-pair">
<label class="config" for="top_only">$T('opt-top_only')</label>
<input type="checkbox" name="top_only" id="top_only" value="1" <!--#if int($top_only) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-top_only')</span>
</div>
<div class="field-pair">
<label class="config" for="pre_check">$T('opt-pre_check')</label>
<input type="checkbox" name="pre_check" id="pre_check" value="1" <!--#if int($pre_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-pre_check')</span>
</div>
<div class="field-pair">
<label class="config" for="fail_hopeless">$T('opt-fail_hopeless')</label>
<input type="checkbox" name="fail_hopeless" id="fail_hopeless" value="1" <!--#if int($fail_hopeless) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-fail_hopeless')</span>
</div>
<div class="field-pair">
<label class="config" for="no_dupes">$T('opt-no_dupes')</label>
<select name="no_dupes" id="no_dupes">
@@ -106,11 +124,6 @@
</select>
<span class="desc">$T('explain-no_series_dupes')</span>
</div>
<div class="field-pair">
<label class="config" for="pause_on_post_processing">$T('opt-pause_on_post_processing')</label>
<input type="checkbox" name="pause_on_post_processing" id="pause_on_post_processing" value="1" <!--#if int($pause_on_post_processing) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-pause_on_post_processing')</span>
</div>
<div class="field-pair">
<label class="config" for="pause_on_pwrar">$T('opt-pause_on_pwrar')</label>
<select name="pause_on_pwrar" id="pause_on_pwrar">
@@ -134,29 +147,12 @@
<input type="text" name="unwanted_extensions" id="unwanted_extensions" value="$unwanted_extensions"/>
<span class="desc">$T('explain-unwanted_extensions')</span>
</div>
<div class="field-pair">
<label class="config" for="top_only">$T('opt-top_only')</label>
<input type="checkbox" name="top_only" id="top_only" value="1" <!--#if int($top_only) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-top_only')</span>
</div>
<div class="field-pair">
<label class="config" for="auto_sort">$T('opt-auto_sort')</label>
<input type="checkbox" name="auto_sort" id="auto_sort" value="1" <!--#if int($auto_sort) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-auto_sort')</span>
</div>
<div class="field-pair">
<label class="config" for="pre_script">$T('opt-pre_script')</label>
<select name="pre_script" id="pre_script">
<!--#for $sc in $script_list#-->
<!--#if $sc.lower() == $pre_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-pre_script')</span>
</div>
<div class="field-pair">
<button class="btn btn-default saveButton"><span class="glyphicon glyphicon-ok"></span> $T('button-saveChanges')</button>
</div>
@@ -170,22 +166,39 @@
<div class="col1">
<fieldset>
<div class="field-pair">
<label class="config" for="ignore_samples">$T('opt-ignore_samples')</label>
<select name="ignore_samples" id="ignore_samples">
<option value="0" <!--#if int($ignore_samples) == 0 then 'selected="selected"' else ""#--> >$T('igsam-off')</option>
<option value="1" <!--#if int($ignore_samples) == 1 then 'selected="selected"' else ""#--> >$T('igsam-del')</option>
</select>
<span class="desc">$T('explain-ignore_samples')</span>
<label class="config" for="pause_on_post_processing">$T('opt-pause_on_post_processing')</label>
<input type="checkbox" name="pause_on_post_processing" id="pause_on_post_processing" value="1" <!--#if int($pause_on_post_processing) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-pause_on_post_processing')</span>
</div>
<div class="field-pair">
<label class="config" for="enable_all_par">$T('opt-enable_all_par')</label>
<input type="checkbox" name="enable_all_par" id="enable_all_par" value="1" <!--#if int($enable_all_par) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_all_par')</span>
</div>
<div class="field-pair">
<label class="config" for="quick_check">$T('opt-quick_check')</label>
<input type="checkbox" name="quick_check" id="quick_check" value="1" <!--#if int($quick_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-quick_check')</span>
</div>
<div class="field-pair <!--#if not $have_multicore then "disabled" else "" #-->">
<label class="config" for="par2_multicore">$T('opt-par2_multicore')</label>
<input type="checkbox" name="par2_multicore" id="par2_multicore" value="1" <!--#if int($par2_multicore) > 0 then 'checked="checked"' else ""#--> <!--#if not $have_multicore then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-par2_multicore')</span>
</div>
<div class="field-pair">
<label class="config" for="enable_all_par">$T('opt-enable_all_par')</label>
<input type="checkbox" name="enable_all_par" id="enable_all_par" value="1" <!--#if int($enable_all_par) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-enable_all_par')</span>
<label class="config" for="par_option">$T('opt-par_option')</label>
<input type="text" name="par_option" id="par_option" value="$par_option" />
<span class="desc">$T('explain-par_option')</span>
</div>
<div class="field-pair">
<label class="config" for="sfv_check">$T('opt-sfv_check')</label>
<input type="checkbox" name="sfv_check" id="sfv_check" value="1" <!--#if int($sfv_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-sfv_check')</span>
</div>
<div class="field-pair">
<label class="config" for="safe_postproc">$T('opt-safe_postproc')</label>
<input type="checkbox" name="safe_postproc" id="safe_postproc" value="1" <!--#if int($safe_postproc) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-safe_postproc')</span>
</div>
<div class="field-pair <!--#if not $have_unrar then "disabled" else "" #-->">
<label class="config" for="enable_unrar">$T('opt-enable_unrar')</label>
@@ -227,21 +240,12 @@
<input type="checkbox" name="enable_tsjoin" id="enable_tsjoin" value="1" <!--#if int($enable_tsjoin) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-ts_join')</span>
</div>
<div class="field-pair">
<label class="config" for="safe_postproc">$T('opt-safe_postproc')</label>
<input type="checkbox" name="safe_postproc" id="safe_postproc" value="1" <!--#if int($safe_postproc) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-safe_postproc')</span>
</div>
<div class="field-pair">
<label class="config" for="sfv_check">$T('opt-sfv_check')</label>
<input type="checkbox" name="sfv_check" id="sfv_check" value="1" <!--#if int($sfv_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-sfv_check')</span>
</div>
<div class="field-pair">
<label class="config" for="unpack_check">$T('opt-unpack_check')</label>
<input type="checkbox" name="unpack_check" id="unpack_check" value="1" <!--#if int($unpack_check) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-unpack_check')</span>
</div>
<div class="field-pair">
<label class="config" for="script_can_fail">$T('opt-script_can_fail')</label>
<input type="checkbox" name="script_can_fail" id="script_can_fail" value="1" <!--#if int($script_can_fail) > 0 then 'checked="checked"' else ""#--> />
@@ -252,16 +256,7 @@
<input type="checkbox" name="new_nzb_on_failure" id="new_nzb_on_failure" value="1" <!--#if int($new_nzb_on_failure) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-new_nzb_on_failure')</span>
</div>
<div class="field-pair <!--#if not $have_multicore then "disabled" else "" #-->">
<label class="config" for="par2_multicore">$T('opt-par2_multicore')</label>
<input type="checkbox" name="par2_multicore" id="par2_multicore" value="1" <!--#if int($par2_multicore) > 0 then 'checked="checked"' else ""#--> <!--#if not $have_multicore then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-par2_multicore')</span>
</div>
<div class="field-pair">
<label class="config" for="par_option">$T('opt-par_option')</label>
<input type="text" name="par_option" id="par_option" value="$par_option" />
<span class="desc">$T('explain-par_option')</span>
</div>
<!--#if not $nt#-->
<div class="field-pair <!--#if not $have_nice then "disabled" else "" #-->">
<label class="config" for="nice">$T('opt-nice')</label>
<input type="text" name="nice" id="nice" value="$nice" <!--#if not $have_nice then 'readonly="readonly" disabled="disabled"' else "" #--> />
@@ -272,6 +267,12 @@
<input type="text" name="ionice" id="ionice" value="$ionice" <!--#if not $have_ionice then 'readonly="readonly" disabled="disabled"' else "" #--> />
<span class="desc">$T('explain-ionice')</span>
</div>
<!--#end if#-->
<div class="field-pair">
<label class="config" for="ignore_samples">$T('opt-ignore_samples')</label>
<input type="checkbox" name="ignore_samples" id="ignore_samples" value="1" <!--#if int($ignore_samples) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-ignore_samples') $T('igsam-del').</span>
</div>
<div class="field-pair">
<label class="config" for="cleanup_list">$T('opt-cleanup_list')</label>
<input type="text" name="cleanup_list" id="cleanup_list" value="$cleanup_list"/>

View File

@@ -262,6 +262,9 @@ textarea:hover, input[type="date"]:hover, input[type="datetime"]:hover, input[ty
.padTable h3 {
margin-top: 0;
}
tr.separator {
height: 30px;
}
.catTable th, .catTable td {
padding: 5px;
}
@@ -284,6 +287,28 @@ textarea:hover, input[type="date"]:hover, input[type="datetime"]:hover, input[ty
.RSS form[action="add_rss_feed"] tr:nth-child(even) {
border: 1px solid #E5E5E5;
}
.Config .table {
margin: 0;
border: 1px solid #ddd
}
.Config .colmask {
margin-bottom: 12px;
}
.Config .padding {
padding: 13px;
}
.Config th {
width: 20%;
min-width: 150px;
padding-left: 15px !important;
}
.Config .label {
font-size: 90%;
}
.Config td .glyphicon-question-sign {
color: black !important;
top: 3px;
}
.tab-pane thead tr {
background-color: transparent !important;
}
@@ -715,6 +740,7 @@ input[type="text"].smaller_input {
select {
min-width: 200px;
max-width: 300px;
}
input[disabled],
@@ -801,6 +827,10 @@ input[type="checkbox"] {
display: none;
}
#navbar .glyphicon-folder-open {
margin-right: 2px;
}
.rss-icon-svg {
display: inline-block;
margin-top: 1px;
@@ -824,6 +854,10 @@ input[type="checkbox"] {
line-height: 1.1em;
}
.Servers .col2.server-disabled .label {
color: ##777 !important;
}
.Servers .col2 .label:nth-child(2) {
opacity: 0.7;
}

View File

@@ -50,7 +50,7 @@
</a>
<div class="dropdown-menu max-speed-input">
<div data-bind="visible: !bandwithLimit()">
<a href="config/general/#bandwidth_max">
<a href="./config/general/#bandwidth_max">
<span class="glyphicon glyphicon-cog"></span> $T('Glitter-setMaxLinespeed')
</a>
</div>
@@ -70,7 +70,7 @@
</li>
<!--#if $have_rss_defined#-->
<li data-tooltip="true" data-placement="bottom" title="$T('cmenu-rss')">
<a href="config/rss">
<a href="./config/rss/">
<svg class="rss-icon-svg" viewBox="0 0 8 8">
<rect class="rss-button" width="8" height="8" />
<circle class="rss-symbol" cx="2" cy="6" r="1" />
@@ -81,7 +81,7 @@
</li>
<!--#end if#-->
<li data-tooltip="true" data-placement="bottom" title="SABnzbd $T('menu-config')">
<a href="config"><span class="glyphicon glyphicon-cog"></span></a>
<a href="./config/"><span class="glyphicon glyphicon-cog"></span></a>
</li>
<li class="dropdown main-menu-link" data-bind="css: { 'active-on-queue-finish-menu': onQueueFinish()}">
<a href="#" data-toggle="dropdown" onclick="keepOpen(this)">
@@ -97,7 +97,7 @@
<!--#if $have_watched_dir#--><li><a href="#" data-bind="click: doQueueAction" data-mode="watched_now">$T('sch-scan_folder')</a></li><!--#end if#-->
<!--#if $pp_pause_event#--><li><a href="#" data-bind="click: doQueueAction" data-mode="resume_pp">$T('sch-resume_post')</a></li><!--#end if#-->
<li class="divider"></li>
<li><a href="shutdown?session=$session" data-bind="click: shutdownSAB">$T('shutdownSab')</a></li>
<li><a href="./shutdown/?session=$session" data-bind="click: shutdownSAB">$T('shutdownSab')</a></li>
<li><a href="#" data-bind="click: restartSAB">$T('Glitter-restartSab')</a></li>
<li class="divider"></li>
<li class="dropdown-header"><span class="glyphicon glyphicon-off"></span> $T('Glitter-onFinish'):</li>

View File

@@ -65,12 +65,21 @@
<div class="col-sm-6">$T('dashboard-NameserverDNS')</div>
<div class="col-sm-6" data-bind="text: !statusInfo.dashboard.dnslookup() ? '$T('dashboard-connectionError')' : statusInfo.dashboard.dnslookup(), css: { 'options-bad-status' : (statusInfo.dashboard.dnslookup() != 'OK') }"></div>
</div>
<hr/>
<div class="row">
<div class="col-sm-6">$T('dashboard-systemPerformance')</div>
<div class="col-sm-6">
<span data-bind="text: statusInfo.dashboard.pystone"></span>
<a href="#" data-bind="click: loadStatusInfo" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
<small data-bind="truncatedText: statusInfo.dashboard.cpumodel, length: 25"></small>
</div>
</div>
<div class="row">
<div class="col-sm-6">$T('dashboard-downloadDirSpeed')</div>
<div class="col-sm-6">
<span data-bind="text: (statusInfo.dashboard.downloaddirspeed() > 0 ? statusInfo.dashboard.downloaddirspeed() : '0'), css: { 'options-bad-status' : statusInfo.dashboard.downloaddirspeedbad() }"></span> MB/s
<a href="#" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
<small>(<span data-bind="truncatedText: statusInfo.dashboard.downloaddir, length: 25"></span>)</small>
<small>(<span data-bind="truncatedText: statusInfo.dashboard.downloaddir, length: 24"></span>)</small>
</div>
</div>
<div class="row">
@@ -78,7 +87,7 @@
<div class="col-sm-6">
<span data-bind="text: (statusInfo.dashboard.completedirspeed() > 0 ? statusInfo.dashboard.completedirspeed() : '0'), css: { 'options-bad-status' : statusInfo.dashboard.completedirspeedbad() }"></span> MB/s
<a href="#" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
<small>(<span data-bind="truncatedText: statusInfo.dashboard.completedir, length: 25"></span>)</small>
<small>(<span data-bind="truncatedText: statusInfo.dashboard.completedir, length: 24"></span>)</small>
</div>
</div>
<div class="row">
@@ -100,7 +109,7 @@
</div>
<div class="row options-function-box">
<div class="col-sm-6">
<a href="status/showlog?session=$session" target="_blank" class="btn btn-default"><span class="glyphicon glyphicon-file"></span> $T('link-showLog')</a>
<a href="./status/showlog?session=$session" target="_blank" class="btn btn-default"><span class="glyphicon glyphicon-file"></span> $T('link-showLog')</a>
</div>
<div class="col-sm-6">
<div class="input-group" data-tooltip="true" data-placement="top" title="$T('logging')">
@@ -128,12 +137,20 @@
</div>
<div data-bind="foreach: statusInfo.status.servers">
<div class="options-server-box">
<a href="#" data-bind="visible: serverblocked(), click: function() { \$parent.unblockServer(servername()) }" class="btn btn-default">$T('Glitter-unblockServer')</a>
<div class="row">
<div class="col-sm-6">$T('swtag-server')</div>
<div class="col-sm-6">
<span data-bind="text: servername"></span><br />
<span data-bind="visible: serverblocked(), text: serverblocked" class="label label-danger"></span>
<span data-bind="text: servername"></span>
</div>
</div>
<div class="row" data-bind="visible: serverblocked()">
<div class="col-sm-12">
<div class="alert alert-danger">
<a href="#" data-bind="visible: serverblocked(), click: function() { \$parent.unblockServer(servername()) }" class="btn btn-default"><span class="glyphicon glyphicon-share-alt"></span> $T('Glitter-unblockServer')</a>
<span data-bind="text: serverblocked()"></span>
</div>
</div>
</div>
<div class="row">
@@ -242,7 +259,7 @@
<option value="40">40 / $T('Glitter-page')</option>
<option value="50">50 / $T('Glitter-page')</option>
<option value="100">100 / $T('Glitter-page')</option>
<option value="9999999">$T('Glitter-everything')</option>
<option value="250">250 / $T('Glitter-page')</option>
</select>
</div>
</div>
@@ -257,7 +274,7 @@
<option value="40">40 / $T('Glitter-page')</option>
<option value="50">50 / $T('Glitter-page')</option>
<option value="100">100 / $T('Glitter-page')</option>
<option value="9999999">$T('Glitter-everything')</option>
<option value="250">250 / $T('Glitter-page')</option>
</select>
</div>
</div>
@@ -362,7 +379,7 @@
<div class="row form-horizontal">
<label class="col-sm-6 control-label">$T('Glitter-addnzbFilename')</label>
<div class="col-sm-6">
<input type="text" name="nzbname" id="nzbname" placeholder="$T('nzo-filename')" class="form-control" />
<input type="text" name="nzbname" id="nzbname" placeholder="$T('name')" class="form-control" />
</div>
</div>
<hr />

View File

@@ -2,9 +2,6 @@
<h2>$T('menu-queue')</h2>
<div class="info-container" data-bind="visible: diskSpaceLeft1()" style="display: none;">
<div class="info-container-box" id="localstorage-error">
<span class="queue-error-info"></span>
</div>
<!-- ko if: hasWarnings() -->
<div class="info-container-box">
<a href="#queue-messages" class="queue-error-info">
@@ -97,8 +94,8 @@
<input type="text" data-bind="value: nameForEdit, visible: editingName(), hasfocus: editingName" />
</form>
<div class="name-options" data-bind="visible: !editingName()">
<a href="#" data-bind="click: editName" class="hover-button"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="#" data-bind="click: showFiles" class="hover-button" title="$T('nzoDetails') - $T('srv-password')"><span class="glyphicon glyphicon-folder-open"></span></a>
<a href="#" data-bind="click: editName, css: { disabled: isGrabbing() }" class="hover-button"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="#" data-bind="click: showFiles, css: { disabled: isGrabbing() }" class="hover-button" title="$T('nzoDetails') - $T('srv-password')"><span class="glyphicon glyphicon-folder-open"></span></a>
<small data-bind="text: avg_age"></small>
</div>
</td>

View File

@@ -21,7 +21,9 @@
<meta name="application-name" content="SABnzbd">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="SABnzbd" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-status-bar-style" content="#000000" />
<meta name="msapplication-navbutton-color" content="#000000" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" sizes="76x76" href="./staticcfg/ico/apple-touch-icon-76x76-precomposed.png" />
<link rel="apple-touch-icon" sizes="120x120" href="./staticcfg/ico/apple-touch-icon-120x120-precomposed.png" />
@@ -59,7 +61,6 @@
glitterTranslate.repair = "$T('explain-Repair')".replace(/<br \/>/g, "\n");
glitterTranslate.removeDown = "$T('Glitter-confirmClearDownloads')";
glitterTranslate.removeDow1 = "$T('Glitter-confirmClear1Download')";
glitterTranslate.grabbing = "$T('Glitter-grabbing')";
glitterTranslate.encrypted = "$T('Glitter-encrypted')";
glitterTranslate.duplicate = "$T('Glitter-duplicate')";
glitterTranslate.tooLarge = "$T('Glitter-tooLarge')";
@@ -74,6 +75,7 @@
glitterTranslate.chooseFile = "$T('Glitter-chooseFile')";
glitterTranslate.orphanedJobsMsg = "$T('explain-orphans')";
glitterTranslate.useCache = "$T('explain-cache_limitstr')";
glitterTranslate.noLocalStorage = "$T('Glitter-noLocalStorage')";
glitterTranslate.updateAvailable = "$T('Glitter-updateAvailable')";
glitterTranslate.defaultText = "$T('default')";
glitterTranslate.noneText = "$T('None')";
@@ -98,6 +100,7 @@
glitterTranslate.status['Script'] = "$T('stage-script')";
glitterTranslate.status['Source'] = "$T('stage-source')";
glitterTranslate.status['Servers'] = "$T('stage-servers')";
glitterTranslate.status['INFO'] = "$T('log-info')".replace('+ ', '').toUpperCase();
glitterTranslate.status['WARNING'] = "$T('Glitter-warning')";
glitterTranslate.status['ERROR'] = "$T('Glitter-error')";

View File

@@ -11,8 +11,9 @@ var fadeOnDeleteDuration = 400; // ms after deleting a row
var isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
// To avoid problems when localStorage is disabled
function localStorageSetItem(varToSet, valueToSet) { try { return localStorage.setItem(varToSet, valueToSet); } catch(e) { $('#localstorage-error span').text('Cannot store settings locally'); } }
function localStorageGetItem(varToGet) { try { return localStorage.getItem(varToGet); } catch(e) { $('#localstorage-error span').text('Cannot store settings locally'); } }
var hasLocalStorage = true;
function localStorageSetItem(varToSet, valueToSet) { try { return localStorage.setItem(varToSet, valueToSet); } catch(e) { hasLocalStorage = false; } }
function localStorageGetItem(varToGet) { try { return localStorage.getItem(varToGet); } catch(e) { hasLocalStorage = false; } }
/**
GLITTER CODE
@@ -166,7 +167,7 @@ $(function() {
var bandwithLimitText = self.bandwithLimit().replace(/[^a-zA-Z]+/g, '');
// Only the number
var speedLimitNumber = (parseInt(self.bandwithLimit()) * (self.speedLimit() / 100));
var speedLimitNumber = (parseFloat(self.bandwithLimit()) * (self.speedLimit() / 100));
// Trick to only get decimal-point when needed
speedLimitNumber = Math.round(speedLimitNumber*10)/10;
@@ -593,11 +594,10 @@ $(function() {
});
})
// Clear warnings through this weird URL..
// Clear warnings through this special URL..
self.clearWarnings = function() {
if(!self.confirmDeleteQueue() || confirm(glitterTranslate.clearWarn))
// Activate
callSpecialAPI("./status/clearwarnings").done(self.refresh)
// Activate
callSpecialAPI("./status/clearwarnings/").done(self.refresh)
}
// Clear messages
@@ -637,6 +637,9 @@ $(function() {
// Shutdown options
self.onQueueFinish.subscribe(function(newValue) {
// Ignore updates before the page is done
if(!self.hasStatusInfo()) return;
// Something changes
callAPI({
mode: 'queue',
@@ -680,6 +683,14 @@ $(function() {
// From the upload
self.addNZBFromFileForm = function(form) {
// Anything?
if(!$(form.nzbFile)[0].files[0]) {
$('.btn-file').css('border-color', 'red')
setTimeout(function() { $('.btn-file').css('border-color', '') }, 2000)
return false;
}
// Upload
self.addNZBFromFile($(form.nzbFile)[0].files[0]);
// After that, hide and reset
@@ -690,6 +701,13 @@ $(function() {
}
// From URL
self.addNZBFromURL = function(form) {
// Anything?
if(!$(form.nzbURL).val()) {
$(form.nzbURL).css('border-color', 'red')
setTimeout(function() { $(form.nzbURL).css('border-color', '') }, 2000)
return false;
}
// Add
callAPI({
mode: "addurl",
@@ -737,6 +755,9 @@ $(function() {
// Load status info
self.loadStatusInfo = function(item, event) {
// Hide tooltips (otherwise they stay forever..)
$('#options-status [data-tooltip="true"]').tooltip('hide')
// Reset
self.hasStatusInfo(false)
@@ -758,7 +779,7 @@ $(function() {
// Only now we can subscribe to the log-level-changes!
self.statusInfo.status.loglevel.subscribe(function(newValue) {
// Update log-level
callSpecialAPI('./status/change_loglevel', {
callSpecialAPI('./status/change_loglevel/', {
loglevel: newValue
});
})
@@ -778,14 +799,14 @@ $(function() {
// Hide before running the test
self.hasStatusInfo(false)
// Run it and then display it
callSpecialAPI('./status/dashrefresh').then(function() {
callSpecialAPI('./status/dashrefresh/').then(function() {
self.loadStatusInfo(true, true)
})
}
// Unblock server
self.unblockServer = function(servername) {
callSpecialAPI("./status/unblock_server", {
callSpecialAPI("./status/unblock_server/", {
server: servername
}).then(function() {
$("#modal-options").modal("hide");
@@ -812,7 +833,7 @@ $(function() {
self.removeAllOrphaned = function() {
if(!self.confirmDeleteHistory() || confirm(glitterTranslate.clearWarn)) {
// Delete them all
callSpecialAPI("./status/delete_all").then(self.loadStatusInfo)
callSpecialAPI("./status/delete_all/").then(self.loadStatusInfo)
}
}
@@ -827,7 +848,7 @@ $(function() {
self.restartSAB = function() {
if(!confirm(glitterTranslate.restart)) return;
// Call restart function
callSpecialAPI("./config/restart")
callSpecialAPI("./config/restart/")
// Set counter, we need at least 15 seconds
self.isRestarting(Math.max(1, Math.floor(15 / self.refreshRate())));
@@ -844,13 +865,13 @@ $(function() {
// Repair queue
self.repairQueue = function() {
if(!confirm(glitterTranslate.repair)) return;
callSpecialAPI("./config/repair").then(function() {
callSpecialAPI("./config/repair/").then(function() {
$("#modal-options").modal("hide");
})
}
// Force disconnect
self.forceDisconnect = function() {
callSpecialAPI("./status/disconnect").then(function() {
callSpecialAPI("./status/disconnect/").then(function() {
$("#modal-options").modal("hide");
})
}
@@ -886,7 +907,7 @@ $(function() {
if(newRelease) {
self.allMessages.push({
index: 'UpdateMsg',
type: 'INFO',
type: glitterTranslate.status['INFO'],
text: ('<a class="queue-update-sab" href="'+newReleaseUrl+'" target="_blank">'+glitterTranslate.updateAvailable+' '+newRelease+' <span class="glyphicon glyphicon-save"></span></a>'),
css: 'info'
});
@@ -896,7 +917,7 @@ $(function() {
if(!response.config.misc.cache_limit && localStorageGetItem('CacheMsg')*1+(1000*3600*24*5) < Date.now()) {
self.allMessages.push({
index: 'CacheMsg',
type: 'INFO',
type: glitterTranslate.status['INFO'],
text: ('<a href="./config/general/#cache_limit">'+glitterTranslate.useCache.replace(/<br \/>/g, " ")+' <span class="glyphicon glyphicon-cog"></span></a>'),
css: 'info',
clear: function() { self.clearMessages('CacheMsg')}
@@ -908,7 +929,7 @@ $(function() {
var orphanMsg = localStorageGetItem('OrphanedMsg')*1+(1000*3600*24*5) < Date.now();
// Delay the check
if(orphanMsg) {
setTimeout(self.loadStatusInfo, 2000);
setTimeout(self.loadStatusInfo, 200);
}
// On any status load we check Orphaned folders
@@ -922,8 +943,8 @@ $(function() {
if(!ko.utils.arrayFirst(self.allMessages(), function(item) { return item.index == 'OrphanedMsg' })) {
self.allMessages.push({
index: 'OrphanedMsg',
type: 'INFO',
text: glitterTranslate.orphanedJobsMsg + ' <a href="#" onclick="$(\'a[href=#modal-options]\').click().parent().click(); $(\'a[href=#options-orphans]\').click()"><span class="glyphicon glyphicon-wrench"></span></a>',
type: glitterTranslate.status['INFO'],
text: glitterTranslate.orphanedJobsMsg + ' <a href="#" onclick="showOrphans()"><span class="glyphicon glyphicon-wrench"></span></a>',
css: 'info',
clear: function() { self.clearMessages('OrphanedMsg')}
});
@@ -936,6 +957,17 @@ $(function() {
}
})
// Message about localStorage not being enabled every 20 days
if(!hasLocalStorage && localStorageGetItem('LocalStorageMsg')*1+(1000*3600*24*20) < Date.now()) {
self.allMessages.push({
index: 'LocalStorageMsg',
type: glitterTranslate.status['WARNING'].replace(':', ''),
text: glitterTranslate.noLocalStorage,
css: 'warning',
clear: function() { self.clearMessages('LocalStorageMsg')}
});
}
/***
Date-stuff
***/
@@ -1562,6 +1594,9 @@ $(function() {
// Edit name
self.editName = function(data, event) {
// Not when still grabbing
if(self.isGrabbing()) return false;
// is there a password in there?
var extractOutput = extractTitleAndPassword(self.name())
@@ -1606,6 +1641,8 @@ $(function() {
// See items
self.showFiles = function() {
// Not when still grabbing
if(self.isGrabbing()) return false;
// Trigger update
parent.parent.filelist.loadFiles(self)
}
@@ -2277,7 +2314,7 @@ $(function() {
dataToSend['action_size'] = Math.abs(nrMoves);
// Activate with this weird URL "API"
callSpecialAPI("./nzb/" + self.currentItem.id + "/bulk_operation", dataToSend)
callSpecialAPI("./nzb/" + self.currentItem.id + "/bulk_operation/", dataToSend)
};
// Remove selected files
@@ -2294,7 +2331,7 @@ $(function() {
})
// Activate with this weird URL "API"
callSpecialAPI("./nzb/" + self.currentItem.id + "/bulk_operation", dataToSend).then(function() {
callSpecialAPI("./nzb/" + self.currentItem.id + "/bulk_operation/", dataToSend).then(function() {
// Fade it out
$('.item-files-table input:checked:not(:disabled)').parents('tr').fadeOut(fadeOnDeleteDuration, function() {
// Set state of the check-all
@@ -2306,7 +2343,7 @@ $(function() {
// For changing the passwords
self.setNzbPassword = function() {
// Activate with this weird URL "API"
callSpecialAPI("./nzb/" + self.currentItem.id + "/save", {
callSpecialAPI("./nzb/" + self.currentItem.id + "/save/", {
name: self.modalTitle(),
password: $('#nzb_password').val()
}).then(function() {
@@ -2629,12 +2666,18 @@ function keepOpen(thisItem) {
// Show history details
function showDetails(thisItem) {
// Open the details of this
// Needs timeout, otherwise it thinks its the 'close' click
setTimeout(function() {
// Unfortunatly the .dropdown('toggle') doesn't work in this setup, so work-a-round
// Open the details of this, or close it?
if($(thisItem).parent().find('.delete>.dropdown').hasClass('open')) {
// One click = close
$(thisItem).parent().find('.delete>.dropdown>a').click()
},1)
} else {
// Needs timeout, otherwise it thinks its the 'close' click for some reason
setTimeout(function() {
$(thisItem).parent().find('.delete>.dropdown>a').click()
},1)
}
}
// Check all functionality
@@ -2701,3 +2744,9 @@ function hideCompletedFiles() {
localStorageSetItem('showCompletedFiles', 'Yes')
}
}
// Show status modal and switch to orphaned jobs tab
function showOrphans() {
$('a[href="#modal-options"]').click().parent().click();
$('a[href="#options-orphans"]').click()
}

View File

@@ -810,7 +810,7 @@ tr.queue-item>td:first-child>a {
}
.table-messages .queue-message-text {
word-break: break-all;
word-wrap: break-word;
}
.table-messages .queue-update-sab {
@@ -915,7 +915,7 @@ tr.queue-item>td:first-child>a {
}
.history-status-table .col-sm-10 {
word-break: break-word;
word-wrap: break-word;
}
.history-status-table a {
@@ -1235,9 +1235,11 @@ tr.queue-item>td:first-child>a {
}
#modal-options .options-server-box .btn {
position: absolute;
right: 10px;
z-index:2000;
float: right;
}
#modal-options .options-server-box .alert {
margin-bottom: 5px;
}
#modal-options .options-server-box:last-child {
@@ -1403,6 +1405,11 @@ tr.queue-item>td:first-child>a {
max-width: 100px;
}
.btn-file,
input[name="nzbURL"] {
transition : border 500ms ease-out;
}
/* HELP MODAL */
#modal-help {

View File

@@ -49,6 +49,8 @@
"localipv4": "$localipv4",
"publicipv4": "$publicipv4",
"ipv6": "$ipv6",
"pystone": "$pystone",
"cpumodel": "$cpumodel",
"dnslookup": "$dnslookup",
<!--#set $downloaddir = $downloaddir.replace('\\','\\\\')#-->
"downloaddir": "$downloaddir",

View File

@@ -134,7 +134,7 @@
<tr class="<!--#if $odd then "odd" else "even"#-->">
<td>$T('dashboard-localIP4')</td>
<td>
<!--#if $publicipv4#-->
<!--#if $localipv4#-->
$localipv4
<!--#else#-->
<strong style="color: red;">$T('dashboard-connectionError')</strong>

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -108,3 +108,6 @@ msgstr "How long or until when do you want to pause? (in English!)"
msgid "Timeleft"
msgstr "Time left"
#: sabnzbd/skintext.py:791 # sabnzbd/skintext.py:871
msgid "Optionally specify a filename"
msgstr "Optionally specify a name"

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -197,9 +197,12 @@ def sig_handler(signum=None, frame=None):
INIT_LOCK = Lock()
def connect_db(thread_index):
def connect_db(thread_index=0):
# Create a connection and store it in the current thread
cherrypy.thread_data.history_db = sabnzbd.database.get_history_handle()
if not (hasattr(cherrypy.thread_data, 'history_db') and cherrypy.thread_data.history_db):
cherrypy.thread_data.history_db = sabnzbd.database.get_history_handle()
return cherrypy.thread_data.history_db
@synchronized(INIT_LOCK)
@@ -285,9 +288,7 @@ def initialize(pause_downloader=False, clean_up=False, evalSched=False, repair=0
lang.set_language(cfg.language())
sabnzbd.api.clear_trans_cache()
# Check for old queue (when a new queue is not present)
if not os.path.exists(os.path.join(cfg.admin_dir.get_path(), QUEUE_FILE_NAME)):
OLD_QUEUE = bool(misc.globber(cfg.admin_dir.get_path(), QUEUE_FILE_TMPL % '?'))
OLD_QUEUE = check_old_queue()
sabnzbd.change_queue_complete_action(cfg.queue_complete(), new=False)
@@ -486,18 +487,24 @@ def guard_fsys_type():
""" Callback for change of file system naming type """
sabnzbd.encoding.change_fsys(cfg.fsys_type())
def guard_https_ver():
""" Callback for change of https verification """
def set_https_verification(value):
prev = False
try:
import ssl
if hasattr(ssl, '_create_default_https_context'):
if cfg.enable_https_verification():
prev = ssl._create_default_https_context == ssl.create_default_context
if value:
ssl._create_default_https_context = ssl.create_default_context
else:
ssl._create_default_https_context = ssl._create_unverified_context
except ImportError:
pass
return prev
def guard_https_ver():
""" Callback for change of https verification """
set_https_verification(cfg.enable_https_verification())
def add_url(url, pp=None, script=None, cat=None, priority=None, nzbname=None):
@@ -1121,6 +1128,24 @@ def wait_for_download_folder():
logging.debug('Waiting for "incomplete" folder')
time.sleep(2.0)
def check_old_queue():
""" Check for old queue (when a new queue is not present) """
old = False
if not os.path.exists(os.path.join(cfg.admin_dir.get_path(), QUEUE_FILE_NAME)):
for ver in (QUEUE_VERSION -1 , QUEUE_VERSION - 2, QUEUE_VERSION - 3):
data = load_admin(QUEUE_FILE_TMPL % str(ver))
if data:
break
try:
old = bool(data and isinstance(data, tuple) and len(data[1]))
except (TypeError, IndexError):
pass
if old and sabnzbd.WIN32 and ver < 10 and sabnzbd.DIR_LCLDATA != sabnzbd.DIR_HOME \
and misc.is_relative_path(cfg.download_dir()):
# For Windows and when version < 10: adjust old default location
cfg.download_dir.set('Documents/' + cfg.download_dir())
return old
# Required wrapper because nzbstuff.py cannot import downloader.py
def highest_server(me):
@@ -1133,11 +1158,11 @@ def proxy_pre_queue(name, pp, cat, script, priority, size, groups):
def test_ipv6():
""" Check if external IPv6 addresses are reachable """
if not cfg.ipv6_test_host():
if not cfg.selftest_host():
# User disabled the test, assume active IPv6
return True
try:
info = socket.getaddrinfo(cfg.ipv6_test_host(), 80, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_IP, socket.AI_CANONNAME)
info = socket.getaddrinfo(cfg.selftest_host(), 443, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_IP, socket.AI_CANONNAME)
except:
logging.debug("Test IPv6: Disabling IPv6, because it looks like it's not available. Reason: %s", sys.exc_info()[0] )
return False

View File

@@ -482,7 +482,7 @@ def _api_history(name, output, kwargs):
special = value.lower()
del_files = bool(int_conv(kwargs.get('del_files')))
if special in ('all', 'failed', 'completed'):
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
if special in ('all', 'failed'):
if del_files:
del_job_files(history_db.get_failed_paths(search))
@@ -1574,7 +1574,7 @@ def options_list(output):
def retry_job(job, new_nzb, password):
""" Re enter failed job in the download queue """
if job:
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
futuretype, url, pp, script, cat = history_db.get_other(job)
if futuretype:
sabnzbd.add_url(url, pp, script, cat)
@@ -1590,7 +1590,7 @@ def retry_job(job, new_nzb, password):
def retry_all_jobs():
""" Re enter all failed jobs in the download queue """
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
return NzbQueue.do.retry_all_jobs(history_db)
@@ -1608,7 +1608,7 @@ def del_hist_job(job, del_files):
if path:
PostProcessor.do.delete(job, del_files=del_files)
else:
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
path = history_db.get_path(job)
PostProcessor.do.delete(job, del_files=del_files)
history_db.remove_history(job)
@@ -1815,7 +1815,7 @@ def build_history(start=None, limit=None, verbose=False, verbose_list=None, sear
# Aquire the db instance
try:
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
close_db = False
except:
# Required for repairs at startup because Cherrypy isn't active yet

View File

@@ -82,8 +82,8 @@ replace_illegal = OptionBool('misc', 'replace_illegal', True)
pre_script = OptionStr('misc', 'pre_script', 'None')
script_can_fail = OptionBool('misc', 'script_can_fail', False)
start_paused = OptionBool('misc', 'start_paused', False)
enable_https_verification = OptionBool('misc', 'enable_https_verification', True)
ipv6_test_host = OptionStr('misc', 'ipv6_test_host', 'test-ipv6.sabnzbd.org')
enable_https_verification = OptionBool('misc', 'enable_https_verification', False)
selftest_host = OptionStr('misc', 'selftest_host', 'self-test.sabnzbd.org')
enable_unrar = OptionBool('misc', 'enable_unrar', True)
enable_unzip = OptionBool('misc', 'enable_unzip', True)

View File

@@ -109,7 +109,7 @@ DEF_QRATE = 0
MIN_DECODE_QUEUE = 5
MAX_DECODE_QUEUE = 10
MAX_WARNINGS = 20
MAX_WIN_DFOLDER = 40
MAX_WIN_DFOLDER = 60
REPAIR_PRIORITY = 3
TOP_PRIORITY = 2

View File

@@ -37,7 +37,7 @@ from sabnzbd.constants import MAX_DECODE_QUEUE, MIN_DECODE_QUEUE
from sabnzbd.articlecache import ArticleCache
import sabnzbd.downloader
import sabnzbd.cfg as cfg
from sabnzbd.encoding import name_fixer
from sabnzbd.encoding import yenc_name_fixer
from sabnzbd.misc import match_str
@@ -245,7 +245,7 @@ def decode(article, data):
try:
for i in xrange(min(40, len(data))):
if data[i].startswith('begin '):
nzf.filename = name_fixer(data[i].split(None, 2)[2])
nzf.filename = yenc_name_fixer(data[i].split(None, 2)[2])
nzf.type = 'uu'
found = True
break
@@ -267,7 +267,7 @@ def decode(article, data):
# Deal with yenc encoded posts
elif (ybegin and yend):
if 'name' in ybegin:
nzf.filename = name_fixer(ybegin['name'])
nzf.filename = yenc_name_fixer(ybegin['name'])
else:
logging.debug("Possible corrupt header detected => ybegin: %s", ybegin)
nzf.type = 'yenc'

View File

@@ -62,11 +62,6 @@ class Server(object):
def __init__(self, id, displayname, host, port, timeout, threads, priority, ssl, ssl_type, send_group, username=None,
password=None, optional=False, retention=0, categories=None):
# If no ssl is protocol set, used highest available one
protocols = ssl_protocols()
if ssl and protocols and ssl_type not in protocols:
ssl_type = protocols[0]
self.id = id
self.newid = None
self.restart = False
@@ -77,7 +72,7 @@ class Server(object):
self.threads = threads
self.priority = priority
self.ssl = ssl
self.ssl_type = ssl_type
self.ssl_type = None
self.optional = optional
self.retention = retention
self.send_group = send_group
@@ -98,6 +93,11 @@ class Server(object):
self.have_body = 'free.xsusenet.com' not in host
self.have_stat = True # Assume server has "STAT", until proven otherwise
if ssl:
# When the user has set a supported protocol, use it
if ssl_type and ssl_type in ssl_protocols():
self.ssl_type = ssl_type
for i in range(threads):
self.idle_threads.append(NewsWrapper(self, i + 1))
@@ -239,8 +239,9 @@ class Downloader(Thread):
@synchronized_CV
def resume(self):
logging.info("Resuming")
if self.paused:
growler.send_notification("SABnzbd", T('Resuming'), 'download')
self.paused = False
growler.send_notification("SABnzbd", T('Resuming'), 'download')
@synchronized_CV
def pause(self, save=True):

View File

@@ -71,17 +71,27 @@ def platform_encode(p):
def name_fixer(p):
""" Return Unicode name of 8bit ASCII string, first try UTF-8, then cp1252 """
""" Return Unicode name of 8bit ASCII string, first try UTF-8, then codepage, then cp1252 """
if isinstance(p, unicode):
return p
elif isinstance(p, str):
try:
return p.decode('utf-8')
except:
return p.decode(codepage)
try:
return p.decode(codepage)
except:
return p.decode('cp1252', 'ignore')
else:
return p
def yenc_name_fixer(p):
""" Return Unicode name of 8bit ASCII string, first try utf-8, then cp1252 """
try:
return p.decode('utf-8')
except:
return p.decode('cp1252')
def is_utf8(p):
""" Return True when p is UTF-8 or plain ASCII """
@@ -251,7 +261,7 @@ def TRANS(p):
if sabnzbd.WIN32:
return p.translate(gTABLE_850_LATIN).decode('cp1252', 'replace')
else:
return p
return unicoder(p)
def UNTRANS(p):

57
sabnzbd/getipaddress.py Normal file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/python -OO
# Copyright 2008-2016 The SABnzbd-Team <team@sabnzbd.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""
sabnzbd.getipaddress
"""
import socket
import sabnzbd
import sabnzbd.cfg
def localipv4():
try:
s_ipv4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s_ipv4.connect(('1.2.3.4', 80)) # Option: use 100.64.1.1 (IANA-Reserved IPv4 Prefix for Shared Address Space)
ipv4 = s_ipv4.getsockname()[0]
s_ipv4.close()
except:
ipv4 = None
pass
return ipv4
def publicipv4():
try:
import urllib2
req = urllib2.Request("http://" + sabnzbd.cfg.selftest_host(), headers={'User-Agent': 'SABnzbd+/%s' % sabnzbd.version.__version__})
f = urllib2.urlopen(req, timeout=2) # timeout 2 seconds, in case website is not accessible
public_ipv4 = f.read()
socket.inet_aton(public_ipv4) # if we got anything else than a plain IPv4 address, this will raise an exception
except:
public_ipv4 = None
return public_ipv4
def ipv6():
try:
s_ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s_ipv6.connect(('2001:db8::8080', 80)) # IPv6 prefix for documentation purpose
ipv6 = s_ipv6.getsockname()[0]
s_ipv6.close()
except:
ipv6 = None
return ipv6

View File

@@ -390,7 +390,7 @@ def send_prowl(title, msg, gtype, force=False, test=None):
prio = sabnzbd.cfg.prowl_prio_complete()
if gtype == 'failed':
prio = sabnzbd.cfg.prowl_prio_failed()
if gtype == 'disk-full':
if gtype == 'disk_full':
prio = sabnzbd.cfg.prowl_prio_disk_full()
if gtype == 'warning':
prio = sabnzbd.cfg.prowl_prio_warning()
@@ -443,7 +443,7 @@ def send_pushover(title, msg, gtype, force=False, test=None):
prio = sabnzbd.cfg.pushover_prio_complete()
if gtype == 'failed':
prio = sabnzbd.cfg.pushover_prio_failed()
if gtype == 'disk-full':
if gtype == 'disk_full':
prio = sabnzbd.cfg.pushover_prio_disk_full()
if gtype == 'warning':
prio = sabnzbd.cfg.pushover_prio_warning()
@@ -541,5 +541,10 @@ def send_pushbullet(title, msg, gtype, force=False, test=None):
def send_windows(title, msg, gtype):
if sabnzbd.WINTRAY:
sabnzbd.WINTRAY.sendnotification(title, msg)
try:
sabnzbd.WINTRAY.sendnotification(title, msg)
except:
logging.info(T('Failed to send Windows notification'))
logging.debug("Traceback: ", exc_info=True)
return T('Failed to send Windows notification')
return None

View File

@@ -26,6 +26,7 @@ import logging
import urllib
import json
import re
import socket
from xml.sax.saxutils import escape
from sabnzbd.utils.rsslib import RSS, Item
@@ -51,6 +52,7 @@ from sabnzbd.nzbqueue import NzbQueue
import sabnzbd.wizard
from sabnzbd.utils.servertests import test_nntp_server_dict
from sabnzbd.utils.sslinfo import ssl_protocols
from sabnzbd.getipaddress import localipv4, publicipv4, ipv6
from sabnzbd.constants import \
REC_RAR_VERSION, NORMAL_PRIORITY, PNFO_NZO_ID_FIELD, PNFO_REPAIR_FIELD, \
@@ -338,8 +340,9 @@ class MainPage(object):
info['preload_queue'] = json.dumps({'queue': remove_callable(queue)});
info['preload_history'] = json.dumps({'history': history});
except UnicodeDecodeError:
info['preload_queue'] = ''
info['preload_history'] = ''
# We use the javascript recognized 'false'
info['preload_queue'] = 'false'
info['preload_history'] = 'false'
template = Template(file=os.path.join(self.__web_dir, 'main.tmpl'),
filter=FILTER, searchList=[info], compilerSettings=DIRECTIVES)
@@ -468,7 +471,7 @@ class MainPage(object):
name = kwargs.get('name')
if name:
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
return ShowString(history_db.get_name(name), history_db.get_script_log(name))
else:
raise dcRaiser(self.__root, kwargs)
@@ -1009,7 +1012,7 @@ class HistoryPage(object):
msg = check_session(kwargs)
if msg:
return msg
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
history_db.remove_history()
raise queueRaiser(self.__root, kwargs)
@@ -1048,7 +1051,7 @@ class HistoryPage(object):
if msg:
return msg
del_files = bool(int_conv(kwargs.get('del_files')))
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
if del_files:
del_job_files(history_db.get_failed_paths())
history_db.remove_failed()
@@ -1099,7 +1102,7 @@ class HistoryPage(object):
return Protected()
name = kwargs.get('name')
if name:
history_db = cherrypy.thread_data.history_db
history_db = sabnzbd.connect_db()
return ShowString(history_db.get_name(name), history_db.get_script_log(name))
else:
raise dcRaiser(self.__root, kwargs)
@@ -1399,7 +1402,7 @@ SPECIAL_BOOL_LIST = \
SPECIAL_VALUE_LIST = \
('size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker',
'req_completion_rate', 'wait_ext_drive', 'history_limit', 'show_sysload', 'ipv6_servers',
'rating_host', 'ipv6_test_host'
'rating_host', 'selftest_host'
)
SPECIAL_LIST_LIST = \
('rss_odd_titles', 'prio_sort_list'
@@ -1804,9 +1807,6 @@ def handle_server(kwargs, root=None, new_svr=False):
for kw in ('ssl', 'send_group', 'enable', 'optional'):
if kw not in kwargs.keys():
kwargs[kw] = None
if 'ssl_type' in kwargs and kwargs['ssl_type'] == ssl_protocols()[0]:
# When user selects highest protocol, make empty (default)
kwargs['ssl_type'] = ''
if svr and not new_svr:
svr.set_dict(kwargs)
else:
@@ -2222,11 +2222,13 @@ class ConfigScheduling(object):
actions_lng = {}
for action in actions:
actions_lng[action] = Ttemplate("sch-" + action)
actions_servers = {}
servers = config.get_servers()
for srv in servers:
name = servers[srv].displayname()
actions.append(name)
actions_lng[name] = name
actions_servers[srv] = servers[srv].displayname()
conf['actions_servers'] = actions_servers
conf['actions'] = actions
conf['actions_lng'] = actions_lng
@@ -2240,13 +2242,7 @@ class ConfigScheduling(object):
if msg:
return msg
# Create server dictionary based on displayname
server_names = {}
servers = config.get_servers()
for srv in servers:
srv = servers[srv]
server_names[srv.displayname()] = srv.ident()[1]
minute = kwargs.get('minute')
hour = kwargs.get('hour')
days_of_week = ''.join([str(x) for x in kwargs.get('daysofweek', '')])
@@ -2267,8 +2263,7 @@ class ConfigScheduling(object):
arguments = 0
elif action in _SCHED_ACTIONS:
arguments = ''
elif action in server_names:
action = server_names[action]
elif action in servers:
if arguments == '1':
arguments = action
action = 'enable_server'
@@ -2462,14 +2457,12 @@ class Status(object):
# Dashboard: Begin
if not kwargs.get('skip_dashboard'):
from sabnzbd.utils.getipaddress import localipv4, publicipv4, ipv6
header['localipv4'] = localipv4()
header['publicipv4'] = publicipv4()
header['ipv6'] = ipv6()
# Dashboard: DNS-check
try:
import socket
socket.gethostbyname('www.google.com')
socket.gethostbyname(cfg.selftest_host())
header['dnslookup'] = "OK"
except:
header['dnslookup'] = None
@@ -2659,17 +2652,12 @@ class Status(object):
msg = check_session(kwargs)
if msg:
return msg
try:
logging.debug('Dashboard: Refresh button pressed')
from sabnzbd.utils.diskspeed import diskspeedmeasure
sabnzbd.downloaddirspeed = round(diskspeedmeasure(sabnzbd.cfg.download_dir.get_path()), 1)
sabnzbd.completedirspeed = round(diskspeedmeasure(sabnzbd.cfg.complete_dir.get_path()), 1)
from sabnzbd.utils.diskspeed import diskspeedmeasure
sabnzbd.downloaddirspeed = round(diskspeedmeasure(sabnzbd.cfg.download_dir.get_path()), 1)
time.sleep(1.0)
sabnzbd.completedirspeed = round(diskspeedmeasure(sabnzbd.cfg.complete_dir.get_path()), 1)
logging.debug('Dashboard: Refresh finished succesfully')
except:
logging.debug('Dashboard: Refresh had a problem')
raise dcRaiser(self.__root, kwargs) # Refresh screen
@@ -2951,7 +2939,6 @@ def rss_history(url, limit=50, search=None):
return rss.write()
def rss_warnings():
""" Return an RSS feed with last warnings/errors """
rss = RSS()
@@ -2968,3 +2955,4 @@ def rss_warnings():
rss.channel.lastBuildDate = std_time(time.time())
rss.channel.pubDate = rss.channel.lastBuildDate
return rss.write()

View File

@@ -446,6 +446,17 @@ def create_real_path(name, loc, path, umask=False, writable=True):
return (False, "")
def is_relative_path(p):
""" Return True if path is relative """
p = p.replace('\\', '/')
if p and p[0] == '/':
return False
if sabnzbd.WIN32 and p and len(p) > 2:
if p[0].isalpha() and p[1] == ':' and p[2] == '/':
return False
return True
def windows_variant():
""" Determine Windows variant
Return vista_plus, x64
@@ -1296,6 +1307,9 @@ def get_base_url(url):
url_host = urlparse(url).hostname
if url_host:
url_split = url_host.split(".")
# Exception for localhost and IPv6 addresses
if len(url_split) < 3:
return url_host
return ".".join(len(url_split[-2]) < 4 and url_split[-3:] or url_split[-2:])
else:
return ''

View File

@@ -476,7 +476,8 @@ def rar_unpack(nzo, workdir, workdir_complete, delete, one_folder, rars):
try:
os.remove(rar)
except OSError:
logging.warning(T('Deleting %s failed!'), rar)
if os.path.exists(rar):
logging.warning(T('Deleting %s failed!'), rar)
brokenrar = '%s.1' % rar
@@ -485,7 +486,8 @@ def rar_unpack(nzo, workdir, workdir_complete, delete, one_folder, rars):
try:
os.remove(brokenrar)
except OSError:
logging.warning(T('Deleting %s failed!'), brokenrar)
if os.path.exists(brokenrar):
logging.warning(T('Deleting %s failed!'), brokenrar)
return fail, extracted_files
@@ -614,6 +616,7 @@ def rar_extract_core(rarfile, numrars, one_folder, nzo, setname, extraction_path
rarfiles = []
fail = 0
inrecovery = False
lines = []
while 1:
line = proc.readline()
@@ -621,6 +624,7 @@ def rar_extract_core(rarfile, numrars, one_folder, nzo, setname, extraction_path
break
line = line.strip()
lines.append(line)
if line.startswith('Extracting from'):
filename = TRANS((re.search(EXTRACTFROM_RE, line).group(1)))
@@ -757,6 +761,7 @@ def rar_extract_core(rarfile, numrars, one_folder, nzo, setname, extraction_path
else:
logging.info('Skipping unrar file check due to unreliable file names or old unrar')
logging.debug('UNRAR output %s', '\n'.join(lines))
nzo.fail_msg = ''
msg = T('Unpacked %s files/folders in %s') % (str(len(extracted)), format_time_string(time() - start))
nzo.set_unpack_info('Unpack', '[%s] %s' % (unicoder(setname), msg), set=setname)
@@ -1213,6 +1218,7 @@ def PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=False, sin
pars = []
datafiles = []
renames = {}
reconstructed = []
linebuf = ''
finished = 0
@@ -1405,18 +1411,25 @@ def PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=False, sin
finished = 1
elif line.startswith('File:') and line.find('data blocks from') > 0:
# Find out if a joinable file has been used for joining
uline = unicoder(line)
for jn in joinables:
if uline.find(os.path.split(jn)[1]) > 0:
used_joinables.append(jn)
break
# Special case of joined RAR files, the "of" and "from" must both be RAR files
# This prevents the joined rars files from being seen as an extra rar-set
m = _RE_BLOCK_FOUND.search(line)
if m and '.rar' in m.group(1).lower() and '.rar' in m.group(2).lower():
if m:
workdir = os.path.split(parfile)[0]
used_joinables.append(os.path.join(workdir, TRANS(m.group(1))))
old_name = TRANS(m.group(1))
new_name = TRANS(m.group(2))
if joinables:
# Find out if a joinable file has been used for joining
uline = unicoder(line)
for jn in joinables:
if uline.find(os.path.split(jn)[1]) > 0:
used_joinables.append(jn)
break
# Special case of joined RAR files, the "of" and "from" must both be RAR files
# This prevents the joined rars files from being seen as an extra rar-set
if '.rar' in old_name.lower() and '.rar' in new_name.lower():
used_joinables.append(os.path.join(workdir, old_name))
else:
logging.debug('PAR2 will reconstruct "%s" from "%s"', new_name, old_name)
reconstructed.append(os.path.join(workdir, old_name))
elif 'Could not write' in line and 'at offset 0:' in line and not classic:
# Hit a bug in par2-tbb, retry with par2-classic
@@ -1496,6 +1509,11 @@ def PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=False, sin
renames[name] = previous[name]
save_data(renames, RENAMES_FILE, nzo.workpath)
# If successful and files were reconstructed, remove incomplete original files
if finished and reconstructed:
# Use 'used_joinables' as a vehicle to get rid of the files
used_joinables.extend(reconstructed)
if retry_classic:
logging.debug('Retry PAR2-joining with par2-classic')
return PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=True, single=single)

View File

@@ -82,7 +82,6 @@ class Article(TryList):
TryList.__init__(self)
self.fetcher = None
self.fetcher_priority = 0
self.allow_fill_server = False
self.article = article
@@ -1012,7 +1011,8 @@ class NzbObject(TryList):
if renames:
for name in renames:
if name in files or renames[name] in files:
files.remove(name)
if name in files:
files.remove(name)
files.append(renames[name])
# Looking for the longest name first, minimizes the chance on a mismatch

View File

@@ -118,6 +118,7 @@ SKIN_TEXT = {
'off' : TT('off'),
'parameters' : TT('Parameters'), #: Config: startup parameters of SABnzbd
'pythonVersion' : TT('Python Version'),
'notAvailable' : TT('Not available'),
'homePage' : TT('Home page'), #: Home page of the SABnzbd project
'source' : TT('Source'), #: Where to find the SABnzbd sourcecode
'or' : TT('or'), #: Used in "IRC or IRC-Webaccess"
@@ -149,6 +150,7 @@ SKIN_TEXT = {
'menu-wiki' : TT('Wiki'), #: Main menu item
'menu-forums' : TT('Forum'), #: Main menu item
'menu-irc' : TT('IRC'), #: Main menu item
'menu-issues' : TT('Issues'), #: Main menu item
'cmenu-general' : TT('General'), #: Main menu item
'cmenu-folders' : TT('Folders'), #: Main menu item
'cmenu-switches' : TT('Switches'), #: Main menu item
@@ -271,7 +273,7 @@ SKIN_TEXT = {
'warning' : TT('Warning'), #: Status page, table column header, actual message
'warnings' : TT('Warnings'), #: Footer: indicator of warnings
'enabled' : TT('Enabled'), #: Status page, indicator that server is enabled
# Dashboard
'dashboard-title' : TT('Dashboard'),
'dashboard-connectionError' : TT('Connection failed!'),
@@ -805,12 +807,12 @@ SKIN_TEXT = {
'Glitter-confirmClearWarnings' : TT('Are you sure?'),
'Glitter-confirmClearDownloads' : TT('Are you sure?'),
'Glitter-confirmClear1Download' : TT('Are you sure?'),
'Glitter-grabbing' : TT('Grabbing NZB...'),
'Glitter-updateAvailable' : TT('Update Available!'),
'Glitter-noLocalStorage' : TT('LocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!'), #: Don't translate LocalStorage
'Glitter-custom' : TT('Custom'),
'Glitter-confirmDeleteQueue' : TT('Confirm Queue Deletions'),
'Glitter-confirmDeleteHistory' : TT('Confirm History Deletions'),
'Glitter-pausePrompt': TT('How long or untill when do you want to pause? (in English!)'),
'Glitter-pausePrompt': TT('How long or untill when do you want to pause? (in English!)'),
'Glitter-pausePromptFail': TT('Sorry, we could not interpret that. Try again.'),
'Glitter-pauseFor' : TT('Pause for...'),
'Glitter-sortAgeAsc' : TT('Sort by Age <small>Oldest&rarr;Newest</small>'),

View File

@@ -40,6 +40,7 @@ class TryList:
def __init__(self):
self.__try_list = []
self.fetcher_priority = 0
@synchronized(TRYLIST_LOCK)
def server_in_try_list(self, server):
@@ -67,3 +68,4 @@ class TryList:
""" Clean the list """
if self.__try_list:
self.__try_list = []
self.fetcher_priority = 0

View File

@@ -201,6 +201,9 @@ class URLGrabber(Thread):
data = fn.read()
fn.close()
# Sanatize filename first
filename = misc.sanitize_filename(filename)
# Write data to temp file
path = os.path.join(cfg.admin_dir.get_path(), FUTURE_Q_FOLDER)
path = os.path.join(path, filename)

View File

@@ -3,40 +3,59 @@
import time
import os
import sys
import logging
_DUMP_DATA = '*' * 10000
def writetofile(filename, mysizeMB):
# writes string to specified file repeat delay, until mysizeMB is reached. Then deletes file
mystring = "The quick brown fox jumps over the lazy dog"
writeloops = int(1000000 * mysizeMB / len(mystring))
# writes string to specified file repeat delay, until mysizeMB is reached.
writeloops = int(1024 * 1024 * mysizeMB / len(_DUMP_DATA))
try:
f = open(filename, 'w')
except:
# no better idea than:
raise
for x in range(0, writeloops):
f.write(mystring)
logging.debug('Cannot create file %s', filename)
logging.debug("Traceback: ", exc_info=True)
return False
try:
for x in xrange(writeloops):
f.write(_DUMP_DATA)
except:
logging.debug('Cannot write to file %s', filename)
logging.debug("Traceback: ", exc_info=True)
return False
f.close()
os.remove(filename)
return True
def diskspeedmeasure(dirname):
# returns writing speed to dirname in MB/s
# method: keep writing a file, until 0.5 seconds is passed. Then divide bytes written by time passed
filesize = 1 # MB
filesize = 10 # MB
maxtime = 0.5 # sec
filename = os.path.join(dirname, 'outputTESTING.txt')
if os.name == 'nt':
# On Windows, this crazy action is needed to
# avoid a "permission denied" error
try:
os.system('echo Hi >%s' % filename)
except:
pass
start = time.time()
loopcounter = 0
while True:
try:
writetofile(filename, filesize)
except:
return None
if not writetofile(filename, filesize):
return 0
loopcounter += 1
diff = time.time() - start
if diff > maxtime:
break
try:
os.remove(filename)
except:
pass
return (loopcounter * filesize) / diff

View File

@@ -1,43 +0,0 @@
#!/usr/bin/python -OO
import socket
def localipv4():
try:
s_ipv4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s_ipv4.connect(('1.2.3.4', 80)) # Option: use 100.64.1.1 (IANA-Reserved IPv4 Prefix for Shared Address Space)
ipv4 = s_ipv4.getsockname()[0]
s_ipv4.close()
except:
ipv4 = None
pass
return ipv4
def publicipv4():
try:
import urllib2
f = urllib2.urlopen("http://api.ipify.org", timeout=2) # timeout 2 seconds, in case website is not accessible
public_ipv4 = f.read()
socket.inet_aton(public_ipv4) # if we got anything else than a plain IPv4 address, this will raise an exception
except:
public_ipv4 = None
pass
return public_ipv4
def ipv6():
try:
s_ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s_ipv6.connect(('2001:db8::8080', 80)) # IPv6 prefix for documentation purpose
ipv6 = s_ipv6.getsockname()[0]
s_ipv6.close()
except:
ipv6 = None
return ipv6
if __name__ == '__main__':
print localipv4()
print publicipv4()
print ipv6()

View File

@@ -1,7 +1,5 @@
_ALL_PROTOCOLS = ('t12', 't11', 't1', 'v23', 'v3', 'v2')
_SSL_PROTOCOLS = {}
def ssl_potential():
''' Return a list of potentially supported SSL protocols'''
try:
@@ -47,17 +45,24 @@ try:
except ImportError:
SSL = None
def ssl_method(method):
''' Translate SSL acronym to a method value '''
if method in _SSL_PROTOCOLS:
return _SSL_PROTOCOLS[method]
else:
return _SSL_PROTOCOLS[0]
# The default is "negotiate a protocol"
try:
return SSL.SSLv23_METHOD
except AttributeError:
return _SSL_PROTOCOLS[0]
def ssl_protocols():
''' Return acronyms for SSL protocols, highest quality first '''
return [p for p in _ALL_PROTOCOLS if p in _SSL_PROTOCOLS]
def ssl_version():
if SSL:
try:
@@ -72,8 +77,19 @@ def ssl_version():
return None
def pyopenssl_version():
if SSL:
try:
import OpenSSL
return OpenSSL.__version__
except ImportError:
return 'No pyOpenSSL installed'
else:
return None
if __name__ == '__main__':
print 'SSL version: %s' % ssl_version()
print 'pyOpenSSL version: %s' % pyopenssl_version()
print 'Potentials: %s' % ssl_potential()
print 'Actuals: %s' % ssl_protocols()