Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixes #9799] Thesaurus selectbox performance in metadata editor is very slow #9800

Merged
merged 16 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
5541acb
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 2, 2022
5cbd8e3
Merge branch 'master' into issue_9799
mwallschlaeger Aug 2, 2022
75df73c
Merge branch 'master' into issue_9799
mattiagiupponi Aug 3, 2022
c83f969
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 4, 2022
8d402fb
Merge branch 'issue_9799' of github.com:mwallschlaeger/geonode into i…
mwallschlaeger Aug 4, 2022
f24000c
Merge pull request #1 from GeoNode/master
mwallschlaeger Aug 4, 2022
c17015d
Merge branch 'master' of github.com:mwallschlaeger/geonode into issue…
mwallschlaeger Aug 4, 2022
8fb9a87
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 4, 2022
038e80d
Merge branch 'master' into issue_9799
mattiagiupponi Aug 8, 2022
2b0d5e2
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 8, 2022
56ffb54
Merge branch 'master' of github.com:GeoNode/geonode into issue_9799
mwallschlaeger Aug 8, 2022
9dc6969
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 8, 2022
0d7e465
Merge pull request #2 from GeoNode/master
mwallschlaeger Aug 8, 2022
a04784f
Merge branch 'master' of github.com:mwallschlaeger/geonode into issue…
mwallschlaeger Aug 8, 2022
ebb8324
Merge branch 'issue_9799' of github.com:mwallschlaeger/geonode into i…
mwallschlaeger Aug 8, 2022
6151ceb
[Fixes #9799] Thesaurus selectbox performance in metadata editor is v…
mwallschlaeger Aug 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions geonode/base/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,18 @@
from taggit.forms import TagField
from tinymce.widgets import TinyMCE
from django.contrib.admin.utils import flatten
from django.utils.translation import get_language

from geonode.base.enumerations import ALL_LANGUAGES
from geonode.base.models import (HierarchicalKeyword,
License, Region, ResourceBase, Thesaurus,
ThesaurusKeyword, ThesaurusKeywordLabel, ThesaurusLabel,
TopicCategory)
from geonode.base.widgets import TaggitSelect2Custom
from geonode.base.fields import MultiThesauriField
from geonode.documents.models import Document
from geonode.layers.models import Dataset
from django.utils.translation import get_language
from .fields import MultiThesauriField
from geonode.base.utils import validate_extra_metadata
from geonode.base.utils import validate_extra_metadata, remove_country_from_lanugecode

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -290,7 +291,14 @@ class Meta:
)


THESAURUS_RESULT_LIST_SEPERATOR = ("", "-------")


class ThesaurusAvailableForm(forms.Form):

# seperator at beginning of thesaurus search result and between
# results found in local language and alt label

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
lang = get_language()
Expand Down Expand Up @@ -337,16 +345,21 @@ def _define_choicefield(self, item, required, tname, lang):

@staticmethod
def _get_thesauro_keyword_label(item, lang):
qs_local = []
qs_non_local = [("", "------")]
for key in ThesaurusKeyword.objects.filter(thesaurus_id=item.id):
label = ThesaurusKeywordLabel.objects.filter(keyword=key).filter(lang=lang)
if label.exists():
qs_local.append((label.get().keyword.id, label.get().label))
else:
qs_non_local.append((key.id, key.alt_label))

return qs_non_local + qs_local
keyword_id_for_given_thesaurus = ThesaurusKeyword.objects.filter(thesaurus_id=item)

# try find results found for given language e.g. (en-us) if no results found remove country code from language to (en) and try again
qs_keyword_ids = ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus).values("keyword_id")
if len(qs_keyword_ids) == 0:
lang = remove_country_from_lanugecode(lang)
qs_keyword_ids = ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus).values("keyword_id")

not_qs_ids = ThesaurusKeywordLabel.objects.exclude(keyword_id__in=qs_keyword_ids).order_by("keyword_id").distinct("keyword_id").values("keyword_id")

qs_local = list(ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus).values_list("keyword_id", "label"))
qs_non_local = list(keyword_id_for_given_thesaurus.filter(id__in=not_qs_ids).values_list("id", "alt_label"))

return [THESAURUS_RESULT_LIST_SEPERATOR] + qs_local + [THESAURUS_RESULT_LIST_SEPERATOR] + qs_non_local

@staticmethod
def _get_thesauro_title_label(item, lang):
Expand Down
21 changes: 20 additions & 1 deletion geonode/base/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
from geonode.storage.manager import storage_manager
from django.test import Client, TestCase, override_settings, SimpleTestCase
from django.shortcuts import reverse
from django.utils import translation

from geonode.base.middleware import ReadOnlyMiddleware, MaintenanceMiddleware
from geonode.base.templatetags.base_tags import get_visibile_resources, facets
Expand All @@ -72,7 +73,7 @@
from django.core.files import File
from django.core.management import call_command
from django.core.management.base import CommandError
from geonode.base.forms import ThesaurusAvailableForm
from geonode.base.forms import ThesaurusAvailableForm, THESAURUS_RESULT_LIST_SEPERATOR


test_image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
Expand Down Expand Up @@ -922,6 +923,24 @@ def test_will_return_thesaurus_with_the_defaul_order_as_0(self):
# will check if the second element of the tuple is the thesaurus_id = 1
self.assertEqual(fields[1][0], '2')

def test_get_thesuro_key_label_with_cmd_language_code(self):
# in python test language code look like 'en' this test checks if key label result function
# returns correct results
tid = 1
translation.activate("en")
t_available_form = ThesaurusAvailableForm(data={"1": tid})
results = t_available_form._get_thesauro_keyword_label(tid, translation.get_language())
self.assertNotEqual(results[1], THESAURUS_RESULT_LIST_SEPERATOR)

def test_get_thesuro_key_label_with_browser_language_code(self):
# in browser scenario language does not look like "it", but rather include coutry code
# like "it-it" this test checks if _get_thesauro_keyword_label can handle this
tid = 1
translation.activate("en-us")
t_available_form = ThesaurusAvailableForm(data={"1": tid})
results = t_available_form._get_thesauro_keyword_label(tid, translation.get_language())
self.assertNotEqual(results[1], THESAURUS_RESULT_LIST_SEPERATOR)


class TestFacets(TestCase):

Expand Down
13 changes: 13 additions & 0 deletions geonode/base/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,16 @@ def validate_extra_metadata(data, instance):
raise ValidationError(f"{e} at index {_index} for input json: {json.dumps(_metadata)}")
# conerted because in this case, we can store a well formated json instead of the user input
return data


@staticmethod
def remove_country_from_lanugecode(language: str):
""" Remove country code (us) from language name (en-us)
>>> remove_country_from_lanugecode("en-us")
'en'
"""
if "-" not in language:
return language

lang, _, _ = language.lower().partition("-")
return lang
37 changes: 20 additions & 17 deletions geonode/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse
from django.utils.translation import get_language

# Geonode dependencies
from geonode.maps.models import Map
Expand All @@ -47,7 +48,7 @@
from geonode.resource.manager import resource_manager
from geonode.security.utils import get_visible_resources
from geonode.notifications_helper import send_notification
from geonode.base.utils import OwnerRightsRequestViewUtils
from geonode.base.utils import OwnerRightsRequestViewUtils, remove_country_from_lanugecode
from geonode.base.forms import UserAndGroupPermissionsForm

from geonode.base.forms import (
Expand Down Expand Up @@ -301,23 +302,25 @@ def get_results(self, context):

class ThesaurusAvailable(autocomplete.Select2QuerySetView):
def get_queryset(self):

tid = self.request.GET.get("sysid")
lang = self.request.GET.get("lang")
qs_local = []
qs_non_local = []
for key in ThesaurusKeyword.objects.filter(thesaurus_id=tid):
label = ThesaurusKeywordLabel.objects.filter(keyword=key).filter(lang=lang)
if self.q:
label = label.filter(label__icontains=self.q)
if label.exists():
qs_local.append(label.get())
else:
if self.q in key.alt_label:
qs_non_local.append(key)
elif not self.q:
qs_non_local.append(key)

return qs_non_local + qs_local
lang = get_language()
keyword_id_for_given_thesaurus = ThesaurusKeyword.objects.filter(thesaurus_id=tid)

# try find results found for given language e.g. (en-us) if no results found remove country code from language to (en) and try again
qs_keyword_ids = ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus).values("keyword_id")
if len(qs_keyword_ids) == 0:
lang = remove_country_from_lanugecode(lang)
qs_keyword_ids = ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus).values("keyword_id")

not_qs_ids = ThesaurusKeywordLabel.objects.exclude(keyword_id__in=qs_keyword_ids).order_by("keyword_id").distinct("keyword_id").values("keyword_id")
qs = ThesaurusKeywordLabel.objects.filter(lang=lang, keyword_id__in=keyword_id_for_given_thesaurus)
if self.q:
qs = qs.filter(label__istartswith=self.q)

qs_local = list(qs)
qs_non_local = list(keyword_id_for_given_thesaurus.filter(id__in=not_qs_ids))
return qs_local + qs_non_local

def get_results(self, context):
return [
Expand Down