def test_launder(self): """Ensure the launder function works as expected. """ self.assertEqual(launder('tm_world_borders_simpl_0.3'), 'tm_world_borders_simpl_0_3') self.assertEqual(launder('Testing#'), 'testing_') self.assertEqual(launder(' '), '_')
def layer_create(request, template='upload/layer_create.html'): if request.method == 'POST': errors = False error_messages = [] if request.is_ajax(): configuration_options = json.loads(request.body) else: configuration_options = request.POST if isinstance(configuration_options.get('featureType', {}), str) \ or isinstance(configuration_options.get('featureType', {}), unicode): configuration_options['featureType'] = json.loads( configuration_options['featureType']) if not configuration_options.get('layer_owner'): configuration_options['layer_owner'] = request.user if configuration_options['featureType'].get('editable') is True: configuration_options['storeCreateGeogig'] = True store_name = '{0}-layers'.format(request.user.username.lower()) configuration_options['featureType']['store']['name'] = store_name # Launder the name of each attribute to ensure that there's no spaces or special characters, # as they will break the functionality of adding and editing features. for attribute in configuration_options['featureType']['attributes']['attribute']: attribute['name'] = launder(attribute['name']) creator = GeoServerLayerCreator() try: layers = creator.handle( configuration_options=configuration_options) except UploadError as e: errors = True error_messages.append( (configuration_options['featureType']['name'], e.message)) if request.is_ajax(): if errors: return HttpResponse(json.dumps({'status': 'failure', 'errors': error_messages}), status=400, content_type='application/json') if layers: layer_names = map(lambda layer: {'name': layer.name, 'url': layer.get_absolute_url()}, Layer.objects.filter(name__in=[n[0] for n in layers])) return HttpResponse(json.dumps({'status': 'success', 'layers': layer_names}), status=201, content_type='application/json') return render_to_response(template, RequestContext(request, {}))
def import_file(self, *args, **kwargs): """ Creates a Geoserver Layer from JSON. { "name": "a new layer", "store": {"name": "store"}, "namespace": {"name": 'name'}, "attributes": {"attribute": [ {"name": "time", "binding": "org.geotools.data.postgis.PostGISDialect$XDate", "minOccurs": 0, "nillable": True}, {"name": "geometry", "binding": "com.vividsolutions.jts.geom.MultiLineString", "minOccurs":0, "nillable":True}]}, "nativeCRS": "EPSG:4326", "srs": "EPSG:4326" } """ self.completed_layers = [] configuration_options = kwargs.get('configuration_options') if not configuration_options: return # Configuration options should be a list at this point since the importer can process multiple layers in a # single import if isinstance(configuration_options, dict): configuration_options = [configuration_options] for layer in configuration_options: feature_type = layer.get('featureType') store_name = feature_type['store']['name'] store_create_geogig = layer.get(u'storeCreateGeogig', 'false') owner = layer.get('layer_owner') username = owner.username email = owner.email layer['layer_type'] = 'vector' layer['fields'] = None layer['geoserver_store'] = {'type': 'geogig'} store = layer.get('geoserver_store') if store.get('type', str).lower() == 'geogig': name = slugify(feature_type['name']) store.setdefault('branch', 'master') store.setdefault('create', 'true') store.setdefault('name', name) store['geogig_repository'] = ("geoserver://%s" % name) store_name = name feature_type['title'] = feature_type['name'] feature_type['name'] = launder(slugify(unicode(feature_type['name']))) # Without this check, the bounding box will default to 0, 0, -1, -1 if 'nativeBoundingBox' not in feature_type: feature_type['nativeBoundingBox'] = {'minx': -180, 'maxx': 180, 'miny': -90, 'maxy': 90, 'crs': 'EPSG:4326'} if store_create_geogig and store_create_geogig != 'false': store_created = create_geoserver_db_featurestore(store_type='geogig', store_name=store_name, author_name=username, author_email=email) feature_type['store']['name'] = store_created.name if store_name not in getattr(settings, 'ALLOWED_DATASTORE_LAYER_CREATE', []) and '*' not in getattr(settings, 'ALLOWED_DATASTORE_LAYER_CREATE', []): return HttpResponseForbidden(content='Datastore specified in featureType is not in the ALLOWED_DATASTORE_LAYER_CREATE whitelist.') for x in range(0, 50): post_request = requests.post( '{}/workspaces/{}/datastores/{}/featuretypes.json'.format(ogc_server_settings.rest, feature_type['namespace']['name'], store_name), data='{{"featureType":{}}}'.format(json.dumps(feature_type)), auth=ogc_server_settings.credentials, headers={'content-type': 'application/json'} ) if post_request.ok: break if 'already exists in' in post_request.content: break time.sleep(3) if post_request.ok: self.completed_layers.append([feature_type['name'], layer]) else: message = 'Unable to create layer: {0}, an unhandled exception occurred.'.format(feature_type['name']) if 'already exists in' in post_request.content: message = 'A layer named {0} already exists. Please choose another name.'.format(feature_type['name']) print post_request.content raise UploadError(message) return self.completed_layers
def layer_create(request, template='upload/layer_create.html'): if request.method == 'POST': errors = False error_messages = [] if request.is_ajax(): configuration_options = json.loads(request.body) else: configuration_options = request.POST if isinstance(configuration_options.get('featureType', {}), str) \ or isinstance(configuration_options.get('featureType', {}), unicode): configuration_options['featureType'] = json.loads( configuration_options['featureType']) if not configuration_options.get('layer_owner'): configuration_options['layer_owner'] = request.user if configuration_options['featureType'].get('editable') is True: configuration_options['storeCreateGeogig'] = True store_name = '{0}-layers'.format(request.user.username.lower()) configuration_options['featureType']['store']['name'] = store_name # Launder the name of each attribute to ensure that there's no spaces or special characters, # as they will break the functionality of adding and editing features. for attribute in configuration_options['featureType']['attributes'][ 'attribute']: attribute['name'] = launder(attribute['name']) creator = GeoServerLayerCreator() try: layers = creator.handle( configuration_options=configuration_options) except UploadError as e: errors = True error_messages.append( (configuration_options['featureType']['name'], e.message)) if request.is_ajax(): if errors: return HttpResponse(json.dumps({ 'status': 'failure', 'errors': error_messages }), status=400, content_type='application/json') if layers: layer_names = map( lambda layer: { 'name': layer.name, 'url': layer.get_absolute_url() }, Layer.objects.filter(name__in=[n[0] for n in layers])) return HttpResponse(json.dumps({ 'status': 'success', 'layers': layer_names }), status=201, content_type='application/json') return render_to_response(template, RequestContext(request, {}))
def import_file(self, *args, **kwargs): """ Creates a Geoserver Layer from JSON. { "name": "a new layer", "store": {"name": "store"}, "namespace": {"name": 'name'}, "attributes": {"attribute": [ {"name": "time", "binding": "org.geotools.data.postgis.PostGISDialect$XDate", "minOccurs": 0, "nillable": True}, {"name": "geometry", "binding": "com.vividsolutions.jts.geom.MultiLineString", "minOccurs":0, "nillable":True}]}, "nativeCRS": "EPSG:4326", "srs": "EPSG:4326" } """ self.completed_layers = [] configuration_options = kwargs.get('configuration_options') if not configuration_options: return # Configuration options should be a list at this point since the importer can process multiple layers in a # single import if isinstance(configuration_options, dict): configuration_options = [configuration_options] for layer in configuration_options: feature_type = layer.get('featureType') datastore = feature_type['store']['name'] store_create_geogig = layer.get(u'storeCreateGeogig', 'false') feature_type['title'] = feature_type['name'] feature_type['name'] = launder(slugify(unicode(feature_type['name']))) # Without this check, the bounding box will default to 0, 0, -1, -1 if 'nativeBoundingBox' not in feature_type: feature_type['nativeBoundingBox'] = {'minx': -180, 'maxx': 180, 'miny': -90, 'maxy': 90, 'crs': 'EPSG:4326'} if store_create_geogig and store_create_geogig != 'false': store_created = create_geoserver_db_featurestore(store_type='geogig', store_name=feature_type['store']['name']) feature_type['store']['name'] = store_created.name if datastore not in getattr(settings, 'ALLOWED_DATASTORE_LAYER_CREATE', []) and '*' not in getattr(settings, 'ALLOWED_DATASTORE_LAYER_CREATE', []): return HttpResponseForbidden(content='Datastore specified in featureType is not in the ALLOWED_DATASTORE_LAYER_CREATE whitelist.') post_request = requests.post( '{}/workspaces/{}/datastores/{}/featuretypes.json'.format(ogc_server_settings.rest, feature_type['namespace']['name'], datastore), data='{{"featureType":{}}}'.format(json.dumps(feature_type)), auth=ogc_server_settings.credentials, headers={'content-type': 'application/json'} ) if post_request.ok: self.completed_layers.append([feature_type['name'], layer]) else: message = 'Unable to create layer: {0}, an unhandled exception occurred.'.format(feature_type['name']) if 'already exists in' in post_request.content: message = 'A layer named {0} already exists. Please choose another name.'.format(feature_type['name']) print post_request.content raise UploadError(message) return self.completed_layers