This repository has been archived by the owner on Jul 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved compatibility shim from geonode.__init__ to geonode.backward_co…
…mpatibility. Added test for shim.
- Loading branch information
1 parent
a7112be
commit c40c970
Showing
6 changed files
with
170 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
osgeo_importer/handlers/geonode/backward_compatibility.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
''' | ||
Created on Nov 9, 2016 | ||
@author: jivan | ||
''' | ||
import datetime | ||
import logging | ||
|
||
from geonode.layers.models import Attribute | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
# The function set_attributes() is used in GeoNodePublishHandler.handle() . | ||
# In case the user is using osgeo_importer with a version of GeoNode older than | ||
# 2016-11-08, commit 005bd559ed97ace87b33d7abd3e84d3e307d4547, duplicate the | ||
# GeoNode-independent set_attributes() here. If this duplicated code is still | ||
# here after 2018-11-01, it should be removed and imports of set_attributes() | ||
# should changed to import from geonode.utils instead of here. | ||
try: | ||
from geonode.utils import set_attributes | ||
except ImportError: | ||
set_attributes = None | ||
|
||
|
||
def set_attributes_bw_compat(layer, attribute_map, overwrite=False, attribute_stats=None): | ||
""" *layer*: a geonode.layers.models.Layer instance | ||
*attribute_map*: a list of 2-lists specifying attribute names and types, | ||
example: [ ['id', 'Integer'], ... ] | ||
*overwrite*: replace existing attributes with new values if name/type matches. | ||
*attribute_stats*: dictionary of return values from get_attribute_statistics(), | ||
of the form to get values by referencing attribute_stats[<layer_name>][<field_name>]. | ||
""" | ||
# we need 3 more items; description, attribute_label, and display_order | ||
attribute_map_dict = { | ||
'field': 0, | ||
'ftype': 1, | ||
'description': 2, | ||
'label': 3, | ||
'display_order': 4, | ||
} | ||
for attribute in attribute_map: | ||
attribute.extend((None, None, 0)) | ||
|
||
attributes = layer.attribute_set.all() | ||
# Delete existing attributes if they no longer exist in an updated layer | ||
for la in attributes: | ||
lafound = False | ||
for attribute in attribute_map: | ||
field, ftype, description, label, display_order = attribute | ||
if field == la.attribute: | ||
lafound = True | ||
# store description and attribute_label in attribute_map | ||
attribute[attribute_map_dict['description']] = la.description | ||
attribute[attribute_map_dict['label']] = la.attribute_label | ||
attribute[attribute_map_dict['display_order']] = la.display_order | ||
if overwrite or not lafound: | ||
logger.debug( | ||
"Going to delete [%s] for [%s]", | ||
la.attribute, | ||
layer.name.encode('utf-8')) | ||
la.delete() | ||
|
||
# Add new layer attributes if they don't already exist | ||
if attribute_map is not None: | ||
iter = len(Attribute.objects.filter(layer=layer)) + 1 | ||
for attribute in attribute_map: | ||
field, ftype, description, label, display_order = attribute | ||
if field is not None: | ||
la, created = Attribute.objects.get_or_create( | ||
layer=layer, attribute=field, attribute_type=ftype, | ||
description=description, attribute_label=label, | ||
display_order=display_order) | ||
if created: | ||
if (not attribute_stats or layer.name not in attribute_stats or | ||
field not in attribute_stats[layer.name]): | ||
result = None | ||
else: | ||
result = attribute_stats[layer.name][field] | ||
|
||
if result is not None: | ||
logger.debug("Generating layer attribute statistics") | ||
la.count = result['Count'] | ||
la.min = result['Min'] | ||
la.max = result['Max'] | ||
la.average = result['Average'] | ||
la.median = result['Median'] | ||
la.stddev = result['StandardDeviation'] | ||
la.sum = result['Sum'] | ||
la.unique_values = result['unique_values'] | ||
la.last_stats_updated = datetime.datetime.now() | ||
la.visible = ftype.find("gml:") != 0 | ||
la.display_order = iter | ||
la.save() | ||
iter += 1 | ||
logger.debug( | ||
"Created [%s] attribute for [%s]", | ||
field, | ||
layer.name.encode('utf-8')) | ||
else: | ||
logger.debug("No attributes found") | ||
|
||
if set_attributes is None: | ||
set_attributes = set_attributes_bw_compat |
Empty file.
Empty file.
Empty file.
64 changes: 64 additions & 0 deletions
64
osgeo_importer/tests/handlers/geonode/test_backward_compatibility.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
''' | ||
Created on Nov 9, 2016 | ||
@author: jivan | ||
''' | ||
import copy | ||
|
||
from django.contrib.auth import get_user_model | ||
from django.db.models import signals | ||
from django.test import TestCase | ||
from geonode.geoserver.signals import geoserver_post_save | ||
|
||
from geonode.layers.models import Layer | ||
from osgeo_importer.handlers.geonode.backward_compatibility import set_attributes_bw_compat as set_attributes | ||
|
||
|
||
class TestSetAttributes(TestCase): | ||
""" This is copied & modified from geonode.tests.utils. | ||
@see backward_compatibility for details. | ||
""" | ||
def setUp(self): | ||
# Load users to log in as | ||
# call_command('loaddata', 'people_data', verbosity=0) | ||
User = get_user_model() | ||
User.objects.create_superuser(username='norman', password='norman', email='') | ||
|
||
def test_set_attributes_creates_attributes(self): | ||
""" Test utility function set_attributes() which creates Attribute instances attached | ||
to a Layer instance. | ||
""" | ||
# Creating a layer requires being logged in | ||
self.client.login(username='norman', password='norman') | ||
|
||
# Disconnect the geoserver-specific post_save signal attached to Layer creation. | ||
# The geoserver signal handler assumes things about the store where the Layer is placed. | ||
# this is a workaround. | ||
disconnected_post_save = signals.post_save.disconnect(geoserver_post_save, sender=Layer) | ||
|
||
# Create dummy layer to attach attributes to | ||
l = Layer.objects.create(name='dummy_layer') | ||
|
||
# Reconnect the signal if it was disconnected | ||
if disconnected_post_save: | ||
signals.post_save.connect(geoserver_post_save, sender=Layer) | ||
|
||
attribute_map = [ | ||
['id', 'Integer'], | ||
['date', 'IntegerList'], | ||
['enddate', 'Real'], | ||
['date_as_date', 'xsd:dateTime'], | ||
] | ||
|
||
# attribute_map gets modified as a side-effect of the call to set_attributes() | ||
expected_results = copy.deepcopy(attribute_map) | ||
|
||
# set attributes for resource | ||
set_attributes(l, attribute_map) | ||
|
||
# 2 items in attribute_map should translate into 2 Attribute instances | ||
self.assertEquals(l.attributes.count(), len(expected_results)) | ||
|
||
# The name and type should be set as provided by attribute map | ||
for a in l.attributes: | ||
self.assertIn([a.attribute, a.attribute_type], expected_results) |