From 96fcef2a84273d231b45203c54f9d43e6256fba8 Mon Sep 17 00:00:00 2001 From: Serge Noiraud Date: Thu, 1 Aug 2019 15:31:39 +0200 Subject: [PATCH] Narrative web: Sort problem with places. (#854) * Narrative web: Sort problem with places. Fixes #10868. Places list is not sorted depending on the selected language. If you start gramps in english or another language then try to generated a narrative web report in another language, the navigation alphabet is incorrect. This is true for the place list and the person list. The problem was related to pyICU. * Narrative web: some pylint improvement. --- gramps/plugins/webreport/common.py | 71 +++++++++++++++++------------- gramps/plugins/webreport/place.py | 14 ++---- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/gramps/plugins/webreport/common.py b/gramps/plugins/webreport/common.py index 5af769e7c..073a25cf7 100644 --- a/gramps/plugins/webreport/common.py +++ b/gramps/plugins/webreport/common.py @@ -316,6 +316,29 @@ def sort_people(dbase, handle_list, rlocale=glocale): return sorted_lists +def sort_places(dbase, handle_list, rlocale=glocale): + """ + will sort the database place + """ + pname_sub = defaultdict(list) + sortnames = {} + + for place_handle in handle_list: + place = dbase.get_place_from_handle(place_handle) + pname = _pd.display(dbase, place) + sortnames[place_handle] = pname + pname_sub[pname].append(place_handle) + + sorted_lists = [] + temp_list = sorted(pname_sub, key=rlocale.sort_key) + + for name in temp_list: + if isinstance(name, bytes): + name = name.decode('utf-8') + sorted_lists.append((name, pname_sub[name][0])) + + return sorted_lists + def sort_event_types(dbase, event_types, event_handle_list, rlocale): """ sort a list of event types and their associated event handles @@ -493,35 +516,23 @@ def first_letter(string, rlocale=glocale): # no special case return norm_unicode[0].upper() -try: - import PyICU # pylint : disable=wrong-import-position - PRIM_COLL = PyICU.Collator.createInstance(PyICU.Locale(COLLATE_LANG)) - PRIM_COLL.setStrength(PRIM_COLL.PRIMARY) +def primary_difference(prev_key, new_key, rlocale=glocale): + """ + The PyICU collation doesn't work if you want to sort in another language + So we use this method to do the work correctly. - def primary_difference(prev_key, new_key, rlocale=glocale): - """ - Try to use the PyICU collation. - """ + Returns true if there is a primary difference between the two parameters + See http://www.gramps-project.org/bugs/view.php?id=2933#c9317 if + letter[i]+'a' < letter[i+1]+'b' and letter[i+1]+'a' < letter[i]+'b' is + true then the letters should be grouped together - return PRIM_COLL.compare(prev_key, new_key) != 0 + The test characters here must not be any that are used in contractions. + """ -except: - def primary_difference(prev_key, new_key, rlocale=glocale): - """ - The PyICU collation is not available. - - Returns true if there is a primary difference between the two parameters - See http://www.gramps-project.org/bugs/view.php?id=2933#c9317 if - letter[i]+'a' < letter[i+1]+'b' and letter[i+1]+'a' < letter[i]+'b' is - true then the letters should be grouped together - - The test characters here must not be any that are used in contractions. - """ - - return rlocale.sort_key(prev_key + "e") >= \ - rlocale.sort_key(new_key + "f") or \ - rlocale.sort_key(new_key + "e") >= \ - rlocale.sort_key(prev_key + "f") + return rlocale.sort_key(prev_key + "e") >= \ + rlocale.sort_key(new_key + "f") or \ + rlocale.sort_key(new_key + "e") >= \ + rlocale.sort_key(prev_key + "f") def get_first_letters(dbase, handle_list, key, rlocale=glocale): """ @@ -565,12 +576,12 @@ def get_first_letters(dbase, handle_list, key, rlocale=glocale): index_list.sort(key=rlocale.sort_key) first = True prev_index = None - for key in index_list[:]: #iterate over a slice copy of the list - if first or primary_difference(prev_index, key, rlocale): + for nkey in index_list[:]: #iterate over a slice copy of the list + if first or primary_difference(prev_index, nkey, rlocale): first = False - prev_index = key + prev_index = nkey else: - index_list.remove(key) + index_list.remove(nkey) # return menu set letters for alphabet_navigation return index_list diff --git a/gramps/plugins/webreport/place.py b/gramps/plugins/webreport/place.py index 05026a4a9..cbbb8f5f0 100644 --- a/gramps/plugins/webreport/place.py +++ b/gramps/plugins/webreport/place.py @@ -64,7 +64,7 @@ from gramps.plugins.webreport.common import (get_first_letters, first_letter, primary_difference, _KEYPLACE, get_index_letter, FULLCLEAR, MARKER_PATH, OSM_MARKERS, MARKERS, - html_escape) + html_escape, sort_places) _ = glocale.translation.sgettext LOG = logging.getLogger(".NarrativeWeb") @@ -181,21 +181,15 @@ class PlacePages(BasePage): ] ) - # bug 9495 : incomplete display of place hierarchy labels - def sort_by_place_name(obj): - """ sort by lower case place name. """ - name = self.report.obj_dict[Place][obj][1] - return name.lower() - - handle_list = sorted(place_handles, - key=lambda x: sort_by_place_name(x)) + handle_list = sort_places(self.r_db, place_handles, + self.rlocale) first = True # begin table body tbody = Html("tbody") table += tbody - for place_handle in handle_list: + for (dummy_pname, place_handle) in handle_list: place = self.r_db.get_place_from_handle(place_handle) if place: if place.get_change_time() > ldatec: