Fixed #1190: Wrong sorting of motion identifier

- Added natural sorting JS plugin for motion DataTables (column identifier).
- Added the new requirements python package 'natsort' for natural sorting of motions in PDF.
This commit is contained in:
Emanuel Schuetze 2014-01-14 21:44:48 +01:00
parent 5a123ade23
commit 13eb0ccb30
9 changed files with 92 additions and 2 deletions

View File

@ -256,6 +256,8 @@ OpenSlides uses the following projects or parts of them:
* `Django haystack <http://haystacksearch.org>`_, License: BSD * `Django haystack <http://haystacksearch.org>`_, License: BSD
* `natsort <https://pypi.python.org/pypi/natsort>`_, License: MIT
* `pdf.js <http://mozilla.github.io/pdf.js/>`_, License: Apache License v2.0 * `pdf.js <http://mozilla.github.io/pdf.js/>`_, License: Apache License v2.0
* `Pillow <https://github.com/python-imaging/Pillow/>`_, License: Standard * `Pillow <https://github.com/python-imaging/Pillow/>`_, License: Standard
@ -292,6 +294,9 @@ OpenSlides uses the following projects or parts of them:
- `jQuery DataTables Plugin <http://www.datatables.net>`_, License: - `jQuery DataTables Plugin <http://www.datatables.net>`_, License:
BSD/GPLv2 BSD/GPLv2
- `DataTables Natural Sort Plugin <http://datatables.net/plug-ins/sorting#natrual>`_,
License: MIT
- `jQuery Cookie Plugin <https://github.com/carhartl/jquery-cookie/>`_, - `jQuery Cookie Plugin <https://github.com/carhartl/jquery-cookie/>`_,
License: MIT/GPL License: MIT/GPL

View File

@ -7,7 +7,7 @@ How to create a new portable Windows distribution of OpenSlides:
2. Install all required python packages (see requirements_production.txt): 2. Install all required python packages (see requirements_production.txt):
easy_install -Z django django-mptt beautifulsoup4 bleach pillow reportlab sockjs_tornado tornado django-haystack whoosh easy_install -Z django django-mptt beautifulsoup4 bleach natsort pillow reportlab sockjs_tornado tornado django-haystack whoosh
3. Install pywin32 from binary installer: 3. Install pywin32 from binary installer:

View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Seth M. Morton
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -93,6 +93,9 @@ SITE_PACKAGES = {
"django-haystack": { "django-haystack": {
"copy": ["haystack"], "copy": ["haystack"],
}, },
"natsort": {
"copy": ["natsort"],
},
"whoosh": { "whoosh": {
"copy": ["whoosh"], "copy": ["whoosh"],
}, },

View File

@ -1,11 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from operator import attrgetter
import os import os
import random import random
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from natsort import natsorted
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib.units import cm from reportlab.lib.units import cm
from reportlab.platypus import PageBreak, Paragraph, Spacer, Table, TableStyle from reportlab.platypus import PageBreak, Paragraph, Spacer, Table, TableStyle
@ -25,6 +27,7 @@ def motions_to_pdf(pdf):
Create a PDF with all motions. Create a PDF with all motions.
""" """
motions = Motion.objects.all() motions = Motion.objects.all()
motions = natsorted(motions, key=attrgetter('identifier'))
all_motion_cover(pdf, motions) all_motion_cover(pdf, motions)
for motion in motions: for motion in motions:
pdf.append(PageBreak()) pdf.append(PageBreak())
@ -254,7 +257,7 @@ def all_motion_cover(pdf, motions):
identifier = "" identifier = ""
if motion.identifier: if motion.identifier:
identifier = "%s " % motion.identifier identifier = "%s " % motion.identifier
pdf.append(Paragraph("%s%s" % (identifier, motion.title), stylesheet['Heading3'])) pdf.append(Paragraph("%s &nbsp; %s" % (identifier, motion.title), stylesheet['Heading3']))
def motion_poll_to_pdf(pdf, poll): def motion_poll_to_pdf(pdf, poll):

View File

@ -12,7 +12,15 @@
{% block javascript %} {% block javascript %}
<script src="{% static 'javascript/jquery.dataTables.min.js' %}" type="text/javascript"></script> <script src="{% static 'javascript/jquery.dataTables.min.js' %}" type="text/javascript"></script>
<script src="{% static 'javascript/naturalSort.js' %}" type="text/javascript"></script>
<script src="{% static 'javascript/dataTables.bootstrap.js' %}" type="text/javascript"></script> <script src="{% static 'javascript/dataTables.bootstrap.js' %}" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
$('#dataTable').dataTable( {
"aoColumnDefs": [
{ "sType": "natural", "aTargets": [ 0 ] }
],
});
</script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}

View File

@ -11,6 +11,7 @@
/* Table initialisation */ /* Table initialisation */
$(document).ready(function() { $(document).ready(function() {
$('#dataTable').dataTable( { $('#dataTable').dataTable( {
"bRetrieve": true,
"aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, gettext("All")]], "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, gettext("All")]],
"aoColumnDefs": [ "aoColumnDefs": [
{ "bSortable": false, "aTargets": [ -1 ] } { "bSortable": false, "aTargets": [ -1 ] }

View File

@ -0,0 +1,50 @@
/*
* Natural Sort algorithm for Javascript - Version 0.6 - Released under MIT license
* Author: Jim Palmer (based on chunking idea from Dave Koelle)
* Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo
*/
function naturalSort (a, b) {
var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
sre = /(^[ ]*|[ ]*$)/g,
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
hre = /^0x[0-9a-f]+$/i,
ore = /^0/,
// convert all to strings and trim()
x = a.toString().replace(sre, '') || '',
y = b.toString().replace(sre, '') || '',
// chunk/tokenize
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
// numeric, hex or date detection
xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
// first try and sort Hex codes or Dates
if (yD)
if ( xD < yD ) return -1;
else if ( xD > yD ) return 1;
// natural sorting through split numeric strings and default strings
for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1;
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
}
if (oFxNcL < oFyNcL) return -1;
if (oFxNcL > oFyNcL) return 1;
}
return 0;
}
// use naturalSort as dataTable extension
jQuery.fn.dataTableExt.oSort['natural-asc'] = function(a,b) {
return naturalSort(a,b);
};
jQuery.fn.dataTableExt.oSort['natural-desc'] = function(a,b) {
return naturalSort(a,b) * -1;
};

View File

@ -4,6 +4,7 @@ beautifulsoup4>=4.3,<4.4
bleach>=1.2,<1.3 bleach>=1.2,<1.3
django-haystack>=2.1,<2.2 django-haystack>=2.1,<2.2
django-mptt>=0.6,<0.7 django-mptt>=0.6,<0.7
natsort>=3.0,<3.1
pillow>=2.2,<2.3 pillow>=2.2,<2.3
reportlab>=2.7,<2.8 reportlab>=2.7,<2.8
sockjs-tornado>=1.0,<1.1 sockjs-tornado>=1.0,<1.1