Browse Source

Add Sorting in RSS tables

pull/743/head
Safihre 9 years ago
committed by shypike
parent
commit
8e29b2a481
  1. 37
      interfaces/Config/templates/config_rss.tmpl
  2. 31
      interfaces/Config/templates/staticcfg/css/style.css
  3. 132
      interfaces/Config/templates/staticcfg/js/jquery.tablesort.min.js
  4. 21
      sabnzbd/interface.py

37
interfaces/Config/templates/config_rss.tmpl

@ -387,11 +387,11 @@
<table class="catTable">
<thead>
<tr>
<th>$T('link-download')</th>
<th class="no-sort">$T('link-download')</th>
<th>$T('rss-skip')</th>
<th>$T('rss-filter')</th>
<th>$T('size')</th>
<th>$T('nzo-age')</th>
<th class="default-sort">$T('nzo-age')</th>
<th>$T('sort-title')</th>
</tr>
</thead>
@ -408,8 +408,8 @@
</td>
<td>$job[2]</td>
<td>$job[3]</td>
<td>$job[5]</td>
<td>$job[7]</td>
<td data-sort-value="$job[6]">$job[5]</td>
<td data-sort-value="$job[8]">$job[7]</td>
<td>$job[1]</td>
</tr>
<!--#end for#-->
@ -423,11 +423,11 @@
<table class="catTable">
<thead>
<tr>
<th>$T('link-download')</th>
<th class="no-sort">$T('link-download')</th>
<th>$T('rss-skip')</th>
<th>$T('rss-filter')</th>
<th>$T('size')</th>
<th>$T('nzo-age')</th>
<th class="default-sort">$T('nzo-age')</th>
<th>$T('sort-title')</th>
</tr>
</thead>
@ -444,8 +444,8 @@
</td>
<td>$job[2]</td>
<td>$job[3]</td>
<td>$job[5]</td>
<td>$job[7]</td>
<td data-sort-value="$job[6]">$job[5]</td>
<td data-sort-value="$job[8]">$job[7]</td>
<td>$job[1]</td>
</tr>
<!--#end for#-->
@ -462,15 +462,15 @@
<table class="catTable">
<thead>
<tr>
<th>$T('rss-added')</th>
<th class="default-sort">$T('rss-added')</th>
<th>$T('size')</th>
<th>$T('sort-title')</th>
</tr>
</thead>
<!--#for $job in $downloaded#-->
<tr class="infoTableSeperator">
<td>$job[6]</td>
<td>$job[5]</td>
<td data-sort-value="$job[10]">$job[9]</td>
<td data-sort-value="$job[6]">$job[5]</td>
<td>$job[1]</td>
</tr>
<!--#end for#-->
@ -485,10 +485,10 @@
</div>
<!-- /colmask -->
<script type="text/javascript" src="${root}staticcfg/js/jquery.tablesort.min.js"></script>
<script type="text/javascript">
function urlencode(str) {
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
}
\$(document).ready(function(){
@ -566,6 +566,17 @@ function urlencode(str) {
\$(objButton).prepend('<span class="glyphicon glyphicon-transfer"></span>')
}
// Enable sorting and set default
if (\$('#rss-tab-matched table').length) {
\$('#rss-tab-matched table').tablesort().data('tablesort').sort(\$('#rss-tab-matched th.default-sort'), 'desc');
}
if (\$('#rss-tab-not-matched table').length) {
\$('#rss-tab-not-matched table').tablesort().data('tablesort').sort(\$('#rss-tab-not-matched th.default-sort'), 'desc');
}
if (\$('#rss-tab-done table').length) {
\$('#rss-tab-done table').tablesort().data('tablesort').sort(\$('#rss-tab-done th.default-sort'), 'desc');
}
\$('.testFeed').click(function(){
setActiveIcon(this)
var whichFeed = \$(this).attr("rel");

31
interfaces/Config/templates/staticcfg/css/style.css

@ -321,6 +321,37 @@ tr.separator {
.RSS form[action="add_rss_feed"] tr:nth-child(even) {
border: 1px solid #E5E5E5;
}
.RSS .tab-pane table th:not(.no-sort) {
cursor: pointer;
}
.RSS .tab-pane table th:not(.sorted) {
padding-right: 12px;
}
.RSS .tab-pane table th.sorted {
padding-right: 0px;
}
.RSS .tab-pane table th.sorted.ascending:after {
content:'';
display: inline-block;
width: 0;
height: 0;
margin-left: 4px;
vertical-align: middle;
border-bottom: 4px dashed;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
}
.RSS .tab-pane table th.sorted.descending:after {
content:'';
display: inline-block;
width: 0;
height: 0;
margin-left: 4px;
vertical-align: middle;
border-top: 4px dashed;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
}
.Config .table {
margin: 0;
border: 1px solid #ddd

132
interfaces/Config/templates/staticcfg/js/jquery.tablesort.min.js

@ -0,0 +1,132 @@
/*
A simple, lightweight jQuery plugin for creating sortable tables.
https://github.com/kylefox/jquery-tablesort
Version 0.0.11
*/
(function($) {
$.tablesort = function ($table, settings) {
var self = this;
this.$table = $table;
this.$thead = this.$table.find('thead');
this.settings = $.extend({}, $.tablesort.defaults, settings);
this.$sortCells = this.$thead.length > 0 ? this.$thead.find('th:not(.no-sort)') : this.$table.find('th:not(.no-sort)');
this.$sortCells.on('click.tablesort', function() {
self.sort($(this));
});
this.index = null;
this.$th = null;
this.direction = null;
};
$.tablesort.prototype = {
sort: function(th, direction) {
var start = new Date(),
self = this,
table = this.$table,
rowsContainer = table.find('tbody').length > 0 ? table.find('tbody') : table,
rows = rowsContainer.find('tr').has('td, th'),
cells = rows.find(':nth-child(' + (th.index() + 1) + ')').filter('td, th'),
sortBy = th.data().sortBy,
sortedMap = [];
var unsortedValues = cells.map(function(idx, cell) {
if (sortBy)
return (typeof sortBy === 'function') ? sortBy($(th), $(cell), self) : sortBy;
return ($(this).data().sortValue != null ? $(this).data().sortValue : $(this).text());
});
if (unsortedValues.length === 0) return;
//click on a different column
if (this.index !== null && this.index !== th.index()) {
this.direction = 'asc';
this.index = th.index();
}
else if (direction !== 'asc' && direction !== 'desc')
this.direction = this.direction === 'asc' ? 'desc' : 'asc';
else
this.direction = direction;
direction = this.direction == 'asc' ? 1 : -1;
self.$table.trigger('tablesort:start', [self]);
self.log("Sorting by " + this.index + ' ' + this.direction);
// Try to force a browser redraw
self.$table.css("display");
// Run sorting asynchronously on a timeout to force browser redraw after
// `tablesort:start` callback. Also avoids locking up the browser too much.
setTimeout(function() {
self.$sortCells.removeClass(self.settings.asc + ' ' + self.settings.desc);
for (var i = 0, length = unsortedValues.length; i < length; i++)
{
sortedMap.push({
index: i,
cell: cells[i],
row: rows[i],
value: unsortedValues[i]
});
}
sortedMap.sort(function(a, b) {
return self.settings.compare(a.value, b.value) * direction;
});
$.each(sortedMap, function(i, entry) {
rowsContainer.append(entry.row);
});
th.addClass(self.settings[self.direction]);
self.log('Sort finished in ' + ((new Date()).getTime() - start.getTime()) + 'ms');
self.$table.trigger('tablesort:complete', [self]);
//Try to force a browser redraw
self.$table.css("display");
}, unsortedValues.length > 2000 ? 200 : 10);
},
log: function(msg) {
if(($.tablesort.DEBUG || this.settings.debug) && console && console.log) {
console.log('[tablesort] ' + msg);
}
},
destroy: function() {
this.$sortCells.off('click.tablesort');
this.$table.data('tablesort', null);
return null;
}
};
$.tablesort.DEBUG = false;
$.tablesort.defaults = {
debug: $.tablesort.DEBUG,
asc: 'sorted ascending',
desc: 'sorted descending',
compare: function(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
};
$.fn.tablesort = function(settings) {
var table, sortable, previous;
return this.each(function() {
table = $(this);
previous = table.data('tablesort');
if(previous) {
previous.destroy();
}
table.data('tablesort', new $.tablesort(table, settings));
});
};
})(window.Zepto || window.jQuery);

21
sabnzbd/interface.py

@ -2810,27 +2810,38 @@ def GetRssLog(feed):
title = xml_name(job.get('title', ''))
size = job.get('size')
age = job.get('age', 0)
age_ms = job.get('age', 0)
time_downloaded = job.get('time_downloaded')
time_downloaded_ms = job.get('time_downloaded')
if size:
size = to_units(size).replace(' ', '&nbsp;')
else:
size = '?'
if sabnzbd.rss.special_rss_site(url):
nzbname = ""
else:
nzbname = xml_name(job.get('title', ''))
if size:
size = to_units(size)
if age:
age = calc_age(age, True)
age_ms = time.mktime(age_ms.timetuple())
if time_downloaded:
time_downloaded = time.strftime(time_format('%H:%M %a %d %b'), time_downloaded).decode(codepage)
time_downloaded_ms = time.mktime(time_downloaded_ms)
# Also return extra fields for sorting
return url, \
title, \
'*' * int(job.get('status', '').endswith('*')), \
job.get('rule', 0), \
nzbname, \
size, \
job.get('size'), \
age, \
age_ms, \
time_downloaded, \
calc_age(age, True)
time_downloaded_ms
jobs = sabnzbd.rss.show_result(feed)
names = jobs.keys()

Loading…
Cancel
Save