forked from openlp/openlp
Precompute the whole comparision key for song sorting.
This commit is contained in:
parent
76ea812629
commit
118f295204
@ -398,25 +398,18 @@ def get_local_key(string):
|
||||
|
||||
def get_natural_key(string):
|
||||
"""
|
||||
Generate a key for locale aware natural string sorting. Returns a list of strings and integers.
|
||||
|
||||
``string``
|
||||
A string, list or tuple which represents the item string.
|
||||
Generate a key for locale aware natural string sorting.
|
||||
Returns a list of string compare keys and integers.
|
||||
"""
|
||||
if isinstance(string, basestring):
|
||||
string = re.findall(r'(\d+|\D+)', string)
|
||||
if len(string) == 1:
|
||||
return list(get_local_key(string[0]))
|
||||
elif isinstance(string, tuple):
|
||||
string = list(string)
|
||||
if isinstance(string, list):
|
||||
for index, part in enumerate(string):
|
||||
if isinstance(part, basestring):
|
||||
if part.isdigit():
|
||||
string[index] = int(part)
|
||||
else:
|
||||
string[index] = get_local_key(part)
|
||||
return string
|
||||
key = re.findall(r'(\d+|\D+)', string)
|
||||
if len(key) == 1:
|
||||
return list(get_local_key(string))
|
||||
for index, part in enumerate(key):
|
||||
if part.isdigit():
|
||||
key[index] = int(part)
|
||||
else:
|
||||
key[index] = get_local_key(part)
|
||||
return key
|
||||
|
||||
|
||||
from applocation import AppLocation
|
||||
|
@ -37,7 +37,6 @@ from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import Registry, UiStrings, create_separated_list, build_icon, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import get_natural_key
|
||||
from openlp.plugins.songs.lib.db import Song
|
||||
from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport
|
||||
|
||||
@ -222,7 +221,7 @@ class SongExportForm(OpenLPWizard):
|
||||
# Load the list of songs.
|
||||
self.application.set_busy_cursor()
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
songs.sort(key=lambda song: get_natural_key(song.sort_key))
|
||||
songs.sort(key=lambda song: song.sort_key)
|
||||
for song in songs:
|
||||
# No need to export temporary songs.
|
||||
if song.temporary:
|
||||
|
@ -38,6 +38,7 @@ from sqlalchemy.orm import mapper, relation, reconstructor
|
||||
from sqlalchemy.sql.expression import func
|
||||
|
||||
from openlp.core.lib.db import BaseModel, init_db
|
||||
from openlp.core.utils import get_natural_key
|
||||
|
||||
|
||||
class Author(BaseModel):
|
||||
@ -69,36 +70,15 @@ class Song(BaseModel):
|
||||
def __init__(self):
|
||||
self.sort_key = ()
|
||||
|
||||
def _try_int(self, s):
|
||||
"""
|
||||
Convert to integer if possible.
|
||||
"""
|
||||
try:
|
||||
return int(s)
|
||||
except:
|
||||
return s.lower()
|
||||
|
||||
def _natsort_key(self, s):
|
||||
"""
|
||||
Used internally to get a tuple by which s is sorted.
|
||||
"""
|
||||
return map(self._try_int, re.findall(r'(\d+|\D+)', s))
|
||||
|
||||
# This decorator tells sqlalchemy to call this method everytime
|
||||
# any data on this object is updated.
|
||||
|
||||
@reconstructor
|
||||
def init_on_load(self):
|
||||
"""
|
||||
Precompute a tuple to be used for sorting.
|
||||
Precompute a natural sorting, locale aware sorting key.
|
||||
|
||||
Song sorting is performance sensitive operation.
|
||||
To get maximum speed lets precompute the string
|
||||
used for comparison.
|
||||
To get maximum speed lets precompute the sorting key.
|
||||
"""
|
||||
# Avoid the overhead of converting string to lowercase and to QString
|
||||
# with every call to sort().
|
||||
self.sort_key = self._natsort_key(self.title)
|
||||
self.sort_key = get_natural_key(self.title)
|
||||
|
||||
|
||||
class Topic(BaseModel):
|
||||
|
@ -38,7 +38,7 @@ from sqlalchemy.sql import or_
|
||||
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, Settings, \
|
||||
UiStrings, translate, check_item_selected, create_separated_list, check_directory_exists
|
||||
from openlp.core.lib.ui import create_widget_action
|
||||
from openlp.core.utils import AppLocation, get_natural_key
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.plugins.songs.forms.editsongform import EditSongForm
|
||||
from openlp.plugins.songs.forms.songmaintenanceform import SongMaintenanceForm
|
||||
from openlp.plugins.songs.forms.songimportform import SongImportForm
|
||||
@ -225,7 +225,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
log.debug(u'display results Song')
|
||||
self.save_auto_select_id()
|
||||
self.list_view.clear()
|
||||
searchresults.sort(key=lambda song: get_natural_key(song.sort_key))
|
||||
searchresults.sort(key=lambda song: song.sort_key)
|
||||
for song in searchresults:
|
||||
# Do not display temporary songs
|
||||
if song.temporary:
|
||||
|
Loading…
Reference in New Issue
Block a user