diff --git a/CHANGES.md b/CHANGES.md
index 573206df..6db214eb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -90,6 +90,10 @@
* Change CPU throttling on General Config/Advanced to "Disabled" by default for new installs
* Change provider OMGWTFNZBS api url and auto reject nuked releases
* Change Search Provider page to load torrent settings only when Search torrents is enabled in Search Settings
+* Add "Order" table column and list failed from newest to oldest wherever possible on Manage Failed Downloads
+* Add number of items shown to Manage Failed Downloads table footer and indicate if number of shown items is limited
+* Add sorting to "Provider" column and fix sorting of "Remove" column on Manage Failed Downloads
+* Fix "Limit" drop down on Manage Failed Downloads
### 0.11.12 (2016-06-20 02:20:00 UTC)
diff --git a/gui/slick/interfaces/default/manage_failedDownloads.tmpl b/gui/slick/interfaces/default/manage_failedDownloads.tmpl
index 3554f270..a6031084 100644
--- a/gui/slick/interfaces/default/manage_failedDownloads.tmpl
+++ b/gui/slick/interfaces/default/manage_failedDownloads.tmpl
@@ -14,74 +14,66 @@
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
-
+
-#if $varExists('header')
+#if $varExists('header')
-#else
+#else
$title
#end if
#set selected = ' selected="selected"'
-
+
-
-#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
\ No newline at end of file
+#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
diff --git a/gui/slick/js/failedDownloads.js b/gui/slick/js/failedDownloads.js
index 1b081ad9..7c59d0f3 100644
--- a/gui/slick/js/failedDownloads.js
+++ b/gui/slick/js/failedDownloads.js
@@ -1,60 +1,75 @@
-$(document).ready(function(){
- $('#submitMassRemove').click(function(){
+$(document).ready(function() {
- var removeArr = new Array()
+ $('#limit').change(function() {
+ window.location.href = sbRoot + '/manage/failedDownloads/?limit=' + $(this).val();
+ });
- $('.removeCheck').each(function() {
- if (this.checked == true) {
- removeArr.push($(this).attr('id').split('-')[1])
- }
- });
+ $('#submitMassRemove').click(function() {
- if (removeArr.length == 0)
- return false
+ var removeArr = [];
- url = sbRoot + '/manage/failedDownloads?toRemove='+removeArr.join('|')
+ $('.removeCheck').each(function() {
+ if (!0 == this.checked) {
+ removeArr.push($(this).attr('id').split('-')[1])
+ }
+ });
- window.location.href = url
+ if (0 == removeArr.length)
+ return !1;
- });
+ window.location.href = sbRoot + '/manage/failedDownloads?toRemove=' + removeArr.join('|');
+ });
- $('.bulkCheck').click(function(){
+ $('.bulkCheck').click(function() {
- var bulkCheck = this;
- var whichBulkCheck = $(bulkCheck).attr('id');
+ var bulkCheck = this, whichBulkCheck = $(bulkCheck).attr('id');
- $('.'+whichBulkCheck+':visible').each(function(){
- this.checked = bulkCheck.checked
- });
- });
+ $('.' + whichBulkCheck + ':visible').each(function() {
+ this.checked = bulkCheck.checked
+ });
+ });
- ['.removeCheck'].forEach(function(name) {
- var lastCheck = null;
+ ['.removeCheck'].forEach(function(name) {
- $(name).click(function(event) {
+ var lastCheck = null;
- if(!lastCheck || !event.shiftKey) {
- lastCheck = this;
- return;
- }
+ $(name).click(function(event) {
- var check = this;
- var found = 0;
+ var table$ = $('#failedTable');
+ if(!lastCheck || !event.shiftKey) {
+ lastCheck = this;
+ $(this).parent('td').attr('data-order', this.checked ? '1' : '0');
+ table$.trigger('update');
+ return;
+ }
- $(name+':visible').each(function() {
- switch (found) {
- case 2: return false;
- case 1:
- this.checked = lastCheck.checked;
- }
+ var check = this, found = 0;
- if (this == check || this == lastCheck)
- found++;
- });
+ $(name + ':visible').each(function() {
+ switch (found) {
+ case 2:
+ return !1;
+ case 1:
+ this.checked = lastCheck.checked;
+ $(this).parent('td').attr('data-order', this.checked ? '1' : '0');
+ }
- });
+ if (this == check || this == lastCheck)
+ found++;
+ });
- });
+ table$.trigger('update');
+ });
+ });
+ $('#failedTable:has(tbody tr)').tablesorter({
+ widgets: ['zebra'],
+ sortList: [[0,0]],
+ sortAppend: [[0,0]],
+ textExtraction: {
+ 0: function(node) { return $(node).attr('data-order'); },
+ 3: function(node) { return $(node).find('img').attr('title'); },
+ 4: function(node) { return $(node).attr('data-order'); }}
+ });
});
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index b69c8a6c..5b08507b 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -3886,10 +3886,12 @@ class Manage(MainHandler):
myDB = db.DBConnection('failed.db')
- if limit == '0':
- sqlResults = myDB.select('SELECT * FROM failed')
+ sql = 'SELECT * FROM failed ORDER BY ROWID DESC'
+ limit = helpers.tryInt(limit, 100)
+ if not limit:
+ sql_results = myDB.select(sql)
else:
- sqlResults = myDB.select('SELECT * FROM failed LIMIT ?', [limit])
+ sql_results = myDB.select(sql + ' LIMIT ?', [limit + 1])
toRemove = toRemove.split('|') if toRemove is not None else []
@@ -3901,8 +3903,9 @@ class Manage(MainHandler):
return self.redirect('/manage/failedDownloads/')
t = PageTemplate(headers=self.request.headers, file='manage_failedDownloads.tmpl')
- t.failedResults = sqlResults
- t.limit = limit
+ t.over_limit = limit and len(sql_results) > limit
+ t.failedResults = t.over_limit and sql_results[0:-1] or sql_results
+ t.limit = str(limit)
t.submenu = self.ManageMenu()
return t.respond()