Skip to content

Commit

Permalink
[Backport to 3.3.x][Fixes #8499] Added GeoApp types missing to search…
Browse files Browse the repository at this point in the history
… filter (#8684)

* [Fixes #8499] Add GeoApp types missing to search filter

* [Fixes #8499] Add GeoApp types missing to search filter

* [Fixes #8499] Fix flake8 issues

* [Fixes #8499] Remove unused variable

* - Including "title-abstract-purpose" filter to the GeoApp resolver

Co-authored-by: afabiani <alessio.fabiani@geo-solutions.it>
  • Loading branch information
mattiagiupponi and afabiani authored Jan 27, 2022
1 parent 5893916 commit 1901138
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 51 deletions.
9 changes: 7 additions & 2 deletions geonode/api/resourcebase_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from geonode.base.models import HierarchicalKeyword
from geonode.base.bbox_utils import filter_bbox
from geonode.groups.models import GroupProfile
from geonode.utils import check_ogc_backend
from geonode.utils import check_ogc_backend, get_subclasses_by_model
from geonode.security.utils import get_visible_resources
from .authentication import OAuthAuthentication
from .authorization import GeoNodeAuthorization, GeonodeApiKeyAuthentication
Expand Down Expand Up @@ -78,6 +78,7 @@
'vector_time': 'vectorTimeSeries',
}
FILTER_TYPES.update(LAYER_SUBTYPES)
GEONODE_APPS_INSTALLED = [x.lower() for x in get_subclasses_by_model('GeoApp')]


class CommonMetaApi:
Expand Down Expand Up @@ -164,7 +165,7 @@ def build_filters(self, filters=None, ignore_bad_filters=False, **kwargs):
if 'type__in' in filters and filters['type__in'] in FILTER_TYPES.keys():
orm_filters.update({'type': filters.getlist('type__in')})
if 'app_type__in' in filters:
orm_filters.update({'polymorphic_ctype__model': filters['app_type__in'].lower()})
orm_filters.update({'polymorphic_ctype__model__in': [filt.lower() for filt in filters.getlist('app_type__in')]})
if 'extent' in filters:
orm_filters.update({'extent': filters['extent']})
orm_filters['f_method'] = filters['f_method'] if 'f_method' in filters else 'and'
Expand All @@ -184,6 +185,7 @@ def apply_filters(self, request, applicable_filters):
keywords = applicable_filters.pop('keywords__slug__in', None)
metadata_only = applicable_filters.pop('metadata_only', False)
filtering_method = applicable_filters.pop('f_method', 'and')
polyphormic_model = applicable_filters.pop('polymorphic_ctype__model__in', None)
if filtering_method == 'or':
filters = Q()
for f in applicable_filters.items():
Expand Down Expand Up @@ -220,6 +222,9 @@ def apply_filters(self, request, applicable_filters):
filtered = filtered | semi_filtered.filter(polymorphic_ctype__model=_type_filter)
else:
filtered = semi_filtered.filter(polymorphic_ctype__model=_type_filter)
elif polyphormic_model:
_type_list = [_t for _t in polyphormic_model if _t in GEONODE_APPS_INSTALLED]
filtered = semi_filtered.filter(polymorphic_ctype__model__in=_type_list)
else:
filtered = semi_filtered

Expand Down
157 changes: 109 additions & 48 deletions geonode/base/templatetags/base_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#
#########################################################################

import logging

from django import template
from django.db.models import Q
from django.conf import settings
Expand All @@ -41,6 +43,8 @@
from geonode.security.utils import get_visible_resources
from collections import OrderedDict

logger = logging.getLogger(__name__)

register = template.Library()

FACETS = {
Expand Down Expand Up @@ -82,7 +86,7 @@ def facets(context):
date_range_filter = request.GET.get('date__range', None)

facet_type = context.get('facet_type', 'all')

facet_geoapp = {}
if not settings.SKIP_PERMS_FILTER:
authorized = []
try:
Expand All @@ -92,53 +96,18 @@ def facets(context):
pass

if facet_type == 'geoapps':
facets = {}

from django.apps import apps
for label, app in apps.app_configs.items():
if hasattr(app, 'type') and app.type == 'GEONODE_APP':
if hasattr(app, 'default_model'):
geoapps = get_visible_resources(
apps.get_model(label, app.default_model).objects.all(),
request.user if request else None,
admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
unpublished_not_visible=settings.RESOURCE_PUBLISHING,
private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)

if category_filter:
geoapps = geoapps.filter(category__identifier__in=category_filter)
if regions_filter:
geoapps = geoapps.filter(regions__name__in=regions_filter)
if owner_filter:
geoapps = geoapps.filter(owner__username__in=owner_filter)
if date_gte_filter:
geoapps = geoapps.filter(date__gte=date_gte_filter)
if date_lte_filter:
geoapps = geoapps.filter(date__lte=date_lte_filter)
if date_range_filter:
geoapps = geoapps.filter(date__range=date_range_filter.split(','))

if extent_filter:
geoapps = filter_bbox(geoapps, extent_filter)

if keywords_filter:
treeqs = HierarchicalKeyword.objects.none()
for keyword in keywords_filter:
try:
kws = HierarchicalKeyword.objects.filter(name__iexact=keyword)
for kw in kws:
treeqs = treeqs | HierarchicalKeyword.get_tree(kw)
except Exception:
# Ignore keywords not actually used?
pass

geoapps = geoapps.filter(Q(keywords__in=treeqs))

if not settings.SKIP_PERMS_FILTER:
geoapps = geoapps.filter(id__in=authorized)

facets[app.default_model] = geoapps.count()
return facets
return _facets_geoapps(
request,
category_filter,
regions_filter,
owner_filter,
date_gte_filter,
date_lte_filter,
date_range_filter,
extent_filter,
keywords_filter,
authorized
)
elif facet_type == 'documents':
documents = Document.objects.filter(title__icontains=title_filter)
if category_filter:
Expand Down Expand Up @@ -323,9 +292,101 @@ def facets(context):

facets['layer'] = facets['raster'] + facets['vector'] + facets['remote'] + facets['wms']

facet_geoapp = _facets_geoapps(
request,
title_filter,
abstract_filter,
purpose_filter,
category_filter,
regions_filter,
owner_filter,
date_gte_filter,
date_lte_filter,
date_range_filter,
extent_filter,
keywords_filter,
authorized
)

facets = {
**facets,
**facet_geoapp
}
return facets


def _facets_geoapps(
request,
title_filter,
abstract_filter,
purpose_filter,
category_filter,
regions_filter,
owner_filter,
date_gte_filter,
date_lte_filter,
date_range_filter,
extent_filter,
keywords_filter,
authorized):
result = {}
from django.apps import apps
for label, app in apps.app_configs.items():
if hasattr(app, 'type') and app.type == 'GEONODE_APP' and hasattr(app, 'default_model'):
geoapps = get_visible_resources(
apps.get_model(label, app.default_model).objects.all(),
request.user if request else None,
admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
unpublished_not_visible=settings.RESOURCE_PUBLISHING,
private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
geoapp_filters = {}
if category_filter:
geoapp_filters['category__identifier__in'] = category_filter
if regions_filter:
geoapp_filters['regions__name__in'] = regions_filter
if owner_filter:
geoapp_filters['owner__username__in'] = owner_filter
if date_gte_filter:
geoapp_filters['date__gte'] = date_gte_filter
if date_lte_filter:
geoapp_filters['date__lte'] = date_lte_filter
if date_range_filter:
geoapp_filters['date__range'] = date_range_filter.split(',')

geoapps = geoapps.filter(**geoapp_filters)

try:
geoapps = geoapps.filter(
Q(title__icontains=title_filter) |
Q(abstract__icontains=abstract_filter) |
Q(purpose__icontains=purpose_filter)
)
except Exception as e:
logger.exception(e)

if extent_filter:
geoapps = filter_bbox(geoapps, extent_filter)

if keywords_filter:
treeqs = HierarchicalKeyword.objects.none()
for keyword in keywords_filter:
try:
kws = HierarchicalKeyword.objects.filter(name__iexact=keyword)
for kw in kws:
treeqs = treeqs | HierarchicalKeyword.get_tree(kw)
except Exception:
# Ignore keywords not actually used?
pass

geoapps = geoapps.filter(Q(keywords__in=treeqs))

if not settings.SKIP_PERMS_FILTER:
geoapps = geoapps.filter(id__in=authorized)

result[app.default_model] = geoapps.count()
return result


@register.filter(is_safe=True)
def get_facet_title(value):
"""Converts a facet_type into a human readable string"""
Expand Down
1 change: 1 addition & 0 deletions geonode/documents/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class SizeRestrictedFileField(forms.FileField):
Same as FileField, but checks file max_size based on the value stored on `field_slug`.
* field_slug - a slug indicating the database object from where the max_size will be retrieved.
"""

def __init__(self, *args, **kwargs):
self.field_slug = kwargs.pop("field_slug")
super(SizeRestrictedFileField, self).__init__(*args, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion geonode/templates/search/_type_filters.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ <h4><a href="#" class="toggle toggle-nav"><i class="fa fa-chevron-down"></i>{% t
{% for facet, count in facets.items %}
{% if count > 0 %}
<li>
<a id="{{ facet }}" data-value="{{ facet }}" data-filter="{{ filter }}" ng-click="multiple_choice_listener($event)">
<a id="{{ facet }}" data-value="{{ facet }}" data-filter={% if facet in GEONODE_APPS_INSTALLED %}app_type__in{% else %}{{ filter }}{% endif %} ng-click="multiple_choice_listener($event)">
{{ facet|get_facet_title|title }}
<span class="badge pull-right">{{ count }}</span>
</a>
Expand Down

0 comments on commit 1901138

Please sign in to comment.