def test_get_valid_user(self): # Verify it accepts an admin user adminuser = get_user_model().objects.get(is_superuser=True) valid_user = get_valid_user(adminuser) msg = ('Passed in a valid admin user "%s" but got "%s" in return' % (adminuser, valid_user)) assert valid_user.id == adminuser.id, msg # Verify it returns a valid user after receiving None valid_user = get_valid_user(None) msg = ('Expected valid user after passing None, got "%s"' % valid_user) assert isinstance(valid_user, get_user_model()), msg newuser = get_user_model().objects.create(username='******') valid_user = get_valid_user(newuser) msg = ('Passed in a valid user "%s" but got "%s" in return' % (newuser, valid_user)) assert valid_user.id == newuser.id, msg valid_user = get_valid_user('arieluser') msg = ('Passed in a valid user by username "%s" but got' ' "%s" in return' % ('arieluser', valid_user)) assert valid_user.username == 'arieluser', msg nn = get_anonymous_user() self.assertRaises(GeoNodeException, get_valid_user, nn)
def test_get_valid_user(self): # Verify it accepts an admin user adminuser = User.objects.get(is_superuser=True) valid_user = get_valid_user(adminuser) msg = ('Passed in a valid admin user "%s" but got "%s" in return' % (adminuser, valid_user)) assert valid_user.id == adminuser.id, msg # Verify it returns a valid user after receiving None valid_user = get_valid_user(None) msg = ('Expected valid user after passing None, got "%s"' % valid_user) assert isinstance(valid_user, User), msg newuser = User.objects.create(username='******') valid_user = get_valid_user(newuser) msg = ('Passed in a valid user "%s" but got "%s" in return' % (newuser, valid_user)) assert valid_user.id == newuser.id, msg valid_user = get_valid_user('arieluser') msg = ('Passed in a valid user by username "%s" but got' ' "%s" in return' % ('arieluser', valid_user)) assert valid_user.username == 'arieluser', msg nn = AnonymousUser() self.assertRaises(GeoNodeException, get_valid_user, nn)
def layer_edit(request, layername, template='layers/layer_edit.html'): """ The view that returns the map composer opened to a map with the given layername. """ user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layer = _resolve_layer(request, layername, 'layers.view_layer', _PERMISSION_MSG_VIEW) maplayer = GXPLayer(name = layer.typename, ows_url = ogc_server_settings.public_url + "wms", layer_params=json.dumps( layer.attribute_config())) layer.srid_url = "http://www.spatialreference.org/ref/" + layer.srid.replace(':','/').lower() + "/" signals.pre_save.disconnect(geoserver_pre_save, sender=Layer) signals.post_save.disconnect(geoserver_post_save, sender=Layer) layer.popular_count += 1 layer.save() signals.pre_save.connect(geoserver_pre_save, sender=Layer) signals.post_save.connect(geoserver_post_save, sender=Layer) # center/zoom don't matter; the viewer will center on the layer bounds map_obj = GXPMap(projection="EPSG:900913") DEFAULT_BASE_LAYERS = default_map_config()[1] config = map_obj.viewer_json(* (DEFAULT_BASE_LAYERS + [maplayer])) return render_to_response(template, RequestContext(request, { 'config': json.dumps(config), 'map': map_obj }))
def file_upload(filename, user=None, title=None, skip=True, overwrite=False, keywords=()): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Do not do attemt to do anything unless geonode is running check_geonode_is_up() # Get a valid user theuser = get_valid_user(user) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # ... and use a url friendly version of that title for the name name = slugify(title).replace('-', '_') # Note that this will replace any existing layer that has the same name # with the data that is being passed. try: layer = Layer.objects.get(name=name) except Layer.DoesNotExist: layer = name new_layer = save(layer, filename, theuser, overwrite, keywords=keywords, title=title) return new_layer
def layer_style(request, layername): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layer = _resolve_layer(request, layername, 'layers.change_layer',_PERMISSION_MSG_MODIFY) style_name = request.POST.get('defaultStyle') # would be nice to implement # better handling of default style switching # in layer model or deeper (gsconfig.py, REST API) old_default = layer.default_style if old_default.name == style_name: return HttpResponse("Default style for %s remains %s" % (layer.name, style_name), status=200) # This code assumes without checking # that the new default style name is included # in the list of possible styles. new_style = (style for style in layer.styles if style.name == style_name).next() # Does this change this in geoserver?? layer.default_style = new_style layer.styles = [s for s in layer.styles if s.name != style_name] + [old_default] layer.save() return HttpResponse("Default style for %s changed to %s" % (layer.name, style_name),status=200)
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 if instance.abstract == '' or instance.abstract is None: instance.abstract = unicode(_('No abstract provided')) if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) if instance.alternate is None: # Set a sensible default for the typename if instance.is_remote: instance.alternate = instance.name else: # use workspace instead of hardcoded geonode instance.alternate = '%s:%s' % (settings.DEFAULT_WORKSPACE, instance.name) base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [ instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1 ] instance.set_bounds_from_bbox(bbox)
def get_bearer_token(app_name='GeoServer', valid_time=30, user_name=None, request=None): ''' Create a bearer token for a given application valid for the time specified in minutes ''' if request and 'access_token' in request.session: return request.session['access_token'] user = get_default_user() if user_name: try: user = get_valid_user(user_name) except Profile.DoesNotExist: pass Application = get_application_model() app = Application.objects.get(name=app_name) token = generate_token() expires = datetime.datetime.now() + datetime.timedelta(minutes=valid_time) AccessToken.objects.get_or_create(user=user, application=app, expires=expires, token=token) return token
def layer_replace(request, layername, template='layers/layer_replace.html'): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layer = _resolve_layer(request, layername, 'layers.change_layer',_PERMISSION_MSG_MODIFY) if request.method == 'GET': cat = Layer.objects.gs_catalog info = cat.get_resource(layer.name) is_featuretype = info.resource_type == FeatureType.resource_type return render_to_response(template, RequestContext(request, {'layer': layer, 'is_featuretype': is_featuretype})) elif request.method == 'POST': form = LayerUploadForm(request.POST, request.FILES) tempdir = None out = {} if form.is_valid(): try: tempdir, base_file = form.write_files() saved_layer = save(layer, base_file, request.user, overwrite=True, permissions=layer.get_all_level_info()) except Exception, e: out['success'] = False out['errors'] = str(e) else: out['success'] = True out['url'] = reverse('layer_detail', args=[saved_layer.typename]) finally:
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): try: _resourcebase_ptr = instance.resourcebase_ptr instance.owner = _resourcebase_ptr.owner instance.uuid = _resourcebase_ptr.uuid instance.bbox_polygon = _resourcebase_ptr.bbox_polygon instance.srid = _resourcebase_ptr.srid except Exception as e: logger.exception(e) if instance.abstract == '' or instance.abstract is None: instance.abstract = 'No abstract provided' if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() logger.debug("handling UUID In pre_save_layer") if hasattr(settings, 'LAYER_UUID_HANDLER') and settings.LAYER_UUID_HANDLER != '': logger.debug("using custom uuid handler In pre_save_layer") from geonode.layers.utils import get_uuid_handler instance.uuid = get_uuid_handler()(instance).create_uuid() else: if instance.uuid == '': instance.uuid = str(uuid.uuid1()) logger.debug("In pre_save_layer") if instance.alternate is None: instance.alternate = _get_alternate_name(instance) logger.debug(f"instance.alternate is: {instance.alternate}") base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = f'.{base_file.name}' if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' if instance.bbox_polygon is None: instance.set_bbox_polygon((-180, -90, 180, 90), 'EPSG:4326') instance.set_bounds_from_bbox(instance.bbox_polygon, instance.srid or instance.bbox_polygon.srid) # Send a notification when a layer is created if instance.pk is None and instance.title: # Resource Created notice_type_label = f'{instance.class_name.lower()}_created' recipients = get_notification_recipients(notice_type_label, resource=instance) send_notification(recipients, notice_type_label, {'resource': instance})
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 if instance.abstract == '' or instance.abstract is None: instance.abstract = unicode(_('No abstract provided')) if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) if instance.alternate is None: # Set a sensible default for the typename if instance.is_remote: instance.alternate = instance.name else: instance.alternate = 'geonode:%s' % instance.name base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [ instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1] instance.set_bounds_from_bbox(bbox)
def handle(self, **options): ignore_errors = options.get('ignore_errors') skip_unadvertised = options.get('skip_unadvertised') remove_deleted = options.get('remove_deleted') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store') if verbosity > 0: console = sys.stdout else: console = None output = gs_slurp( ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace, store=store, filter=filter, skip_unadvertised=skip_unadvertised, remove_deleted=remove_deleted) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output['layers']: if dict_['status'] == 'failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if remove_deleted: print "Detailed report of layers to be deleted from GeoNode that failed:" for dict_ in output['deleted_layers']: if dict_['status'] == 'delete_failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % ( len(output['layers']), round(output['stats']['duration_sec'], 2)) print "%d Created layers" % output['stats']['created'] print "%d Updated layers" % output['stats']['updated'] print "%d Failed layers" % output['stats']['failed'] try: duration_layer = round( output['stats']['duration_sec'] * 1.0 / len(output['layers']), 2) except ZeroDivisionError: duration_layer = 0 if len(output) > 0: print "%f seconds per layer" % duration_layer if remove_deleted: print "\n%d Deleted layers" % output['stats']['deleted']
def handle(self, **options): ignore_errors = options.get('ignore_errors') skip_unadvertised = options.get('skip_unadvertised') remove_deleted = options.get('remove_deleted') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store') if verbosity > 0: console = sys.stdout else: console = None output = gs_slurp(ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace, store=store, filter=filter, skip_unadvertised=skip_unadvertised, remove_deleted=remove_deleted) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output['layers']: if dict_['status'] == 'failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if remove_deleted: print "Detailed report of layers to be deleted from GeoNode that failed:" for dict_ in output['deleted_layers']: if dict_['status'] == 'delete_failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % (len( output['layers']), round(output['stats']['duration_sec'], 2)) print "%d Created layers" % output['stats']['created'] print "%d Updated layers" % output['stats']['updated'] print "%d Failed layers" % output['stats']['failed'] try: duration_layer = round( output['stats']['duration_sec'] * 1.0 / len(output['layers']), 2) except ZeroDivisionError: duration_layer = 0 if len(output) > 0: print "%f seconds per layer" % duration_layer if remove_deleted: print "\n%d Deleted layers" % output['stats']['deleted']
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 instance.srid = instance.resourcebase_ptr.srid if instance.abstract == '' or instance.abstract is None: instance.abstract = unicode(_('Resumo nao fornecido')) if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) logger.debug("In pre_save_layer") if instance.alternate is None: instance.alternate = _get_alternate_name(instance) logger.debug("instance.alternate is: {}".format(instance.alternate)) base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [ instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1] instance.set_bounds_from_bbox(bbox, instance.srid)
def handle(self, *args, **options): name = options.get('name') username = options.get('user') user = get_valid_user(username) title = options.get('title') geometry_type = options.get('geometry') attributes = options.get('attributes') create_layer(name, title, user, geometry_type, attributes)
def handle(self, *args, **options): name = options.get('name') username = options.get('user') user = get_valid_user(username) title = options.get('title') geometry_type = options.get('geometry') attributes = options.get('attributes') create_dataset(name, title, user, geometry_type, attributes)
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 if instance.abstract == '' or instance.abstract is None: instance.abstract = unicode(_('Layer abstract is very important! You are requested to update it now.')) if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) if instance.typename is None: # Set a sensible default for the typename instance.typename = 'geonode:%s' % instance.name base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [ instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1] instance.set_bounds_from_bbox(bbox)
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 if instance.abstract == '' or instance.abstract is None: instance.abstract = 'No abstract provided' if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) if instance.typename is None: # Set a sensible default for the typename instance.typename = 'geonode:%s' % instance.name base_file = instance.get_base_file() if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1] instance.set_bounds_from_bbox(bbox) try: instance.thumbnail, created = Thumbnail.objects.get_or_create(resourcebase__id=instance.id) except MultipleObjectsReturned: instance.thumbnail = Thumbnail.objects.filter(resourcebase__id=instance.id)[0]
def handle(self, **options): ignore_errors = options.get('ignore_errors') skip_unadvertised = options.get('skip_unadvertised') skip_geonode_registered = options.get('skip_geonode_registered') remove_deleted = options.get('remove_deleted') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store')
def handle(self, **options): ignore_errors = options.get('ignore_errors') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store') if verbosity > 0: console = sys.stdout else: console = None start = datetime.datetime.now() output = gs_slurp(ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace, store=store, filter=filter) updated = [ dict_['name'] for dict_ in output if dict_['status'] == 'updated' ] created = [ dict_['name'] for dict_ in output if dict_['status'] == 'created' ] failed = [ dict_['name'] for dict_ in output if dict_['status'] == 'failed' ] finish = datetime.datetime.now() td = finish - start duration = td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600 duration_rounded = round(duration, 2) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output: if dict_['status'] == 'failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % ( len(output), duration_rounded) print "%d Created layers" % len(created) print "%d Updated layers" % len(updated) print "%d Failed layers" % len(failed) if len(output) > 0: print "%f seconds per layer" % (duration * 1.0 / len(output))
def pre_save_layer(instance, sender, **kwargs): if kwargs.get("raw", False): instance.owner = instance.resourcebase_ptr.owner instance.uuid = instance.resourcebase_ptr.uuid instance.bbox_x0 = instance.resourcebase_ptr.bbox_x0 instance.bbox_x1 = instance.resourcebase_ptr.bbox_x1 instance.bbox_y0 = instance.resourcebase_ptr.bbox_y0 instance.bbox_y1 = instance.resourcebase_ptr.bbox_y1 if instance.abstract == "" or instance.abstract is None: instance.abstract = "No abstract provided" if instance.title == "" or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == "": instance.uuid = str(uuid.uuid1()) if instance.typename is None: # Set a sensible default for the typename instance.typename = "geonode:%s" % instance.name base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = ".%s" % base_file.name if extension in vec_exts: instance.storeType = "dataStore" elif extension in cov_exts: instance.storeType = "coverageStore" # Set sane defaults for None in bbox fields. if instance.bbox_x0 is None: instance.bbox_x0 = -180 if instance.bbox_x1 is None: instance.bbox_x1 = 180 if instance.bbox_y0 is None: instance.bbox_y0 = -90 if instance.bbox_y1 is None: instance.bbox_y1 = 90 bbox = [instance.bbox_x0, instance.bbox_x1, instance.bbox_y0, instance.bbox_y1] instance.set_bounds_from_bbox(bbox)
def pre_save_layer(instance, sender, **kwargs): if kwargs.get('raw', False): try: _resourcebase_ptr = instance.resourcebase_ptr instance.owner = _resourcebase_ptr.owner instance.uuid = _resourcebase_ptr.uuid instance.bbox_polygon = _resourcebase_ptr.bbox_polygon instance.srid = _resourcebase_ptr.srid except Exception as e: logger.exception(e) if instance.abstract == '' or instance.abstract is None: instance.abstract = 'No abstract provided' if instance.title == '' or instance.title is None: instance.title = instance.name # Set a default user for accountstream to work correctly. if instance.owner is None: instance.owner = get_valid_user() if instance.uuid == '': instance.uuid = str(uuid.uuid1()) logger.debug("In pre_save_layer") if instance.alternate is None: instance.alternate = _get_alternate_name(instance) logger.debug("instance.alternate is: {}".format(instance.alternate)) base_file, info = instance.get_base_file() if info: instance.info = info if base_file is not None: extension = '.%s' % base_file.name if extension in vec_exts: instance.storeType = 'dataStore' elif extension in cov_exts: instance.storeType = 'coverageStore' if instance.bbox_polygon is None: instance.set_bbox_polygon((-180, -90, 180, 90), 'EPSG:4326') instance.set_bounds_from_bbox(instance.bbox_polygon, instance.bbox_polygon.srid) # Send a notification when a layer is created if instance.pk is None and instance.title: # Resource Created notice_type_label = '%s_created' % instance.class_name.lower() recipients = get_notification_recipients(notice_type_label, resource=instance) send_notification(recipients, notice_type_label, {'resource': instance})
def layer_remove(request, layername, template='layers/layer_remove.html'): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layer = _resolve_layer(request, layername, 'layers.delete_layer',_PERMISSION_MSG_DELETE) if (request.method == 'GET'): return render_to_response(template,RequestContext(request, { "layer": layer })) if (request.method == 'POST'): layer.delete() return HttpResponseRedirect(reverse("layer_browse")) else: return HttpResponse("Not allowed",status=403)
def layer_change_poc(request, ids, template = 'layers/layer_change_poc.html'): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layers = Layer.objects.filter(id__in=ids.split('_')) if request.method == 'POST': form = PocForm(request.POST) if form.is_valid(): for layer in layers: layer.poc = form.cleaned_data['contact'] layer.save() # Process the data in form.cleaned_data # ... return HttpResponseRedirect('/admin/maps/layer') # Redirect after POST else: form = PocForm() # An unbound form return render_to_response(template, RequestContext(request, {'layers': layers, 'form': form }))
def feature_edit_check(request, layername): """ If the layer is not a raster and the user has edit permission, return a status of 200 (OK). Otherwise, return a status of 401 (unauthorized). """ try: user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username except: ogc_server_settings.DATASTORE = ogc_server_settings.DATASTORE layer = get_object_or_404(Layer, typename=layername) feature_edit = getattr(settings, "GEOGIT_DATASTORE", None) or ogc_server_settings.DATASTORE if request.user.has_perm('maps.change_layer', obj=layer) and layer.storeType == 'dataStore' and feature_edit: return HttpResponse(json.dumps({'authorized': True}), mimetype="application/json") else: return HttpResponse(json.dumps({'authorized': False}), mimetype="application/json")
def layer_upload(request, template='upload/layer_upload.html'): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username if request.method == 'GET': return render_to_response(template, RequestContext(request, {})) elif request.method == 'POST': form = NewLayerUploadForm(request.POST, request.FILES) tempdir = None errormsgs = [] out = {'success': False} if form.is_valid(): title = form.cleaned_data["layer_title"] # Replace dots in filename - GeoServer REST API upload bug # and avoid any other invalid characters. # Use the title if possible, otherwise default to the filename if title is not None and len(title) > 0: name_base = title else: name_base, __ = os.path.splitext(form.cleaned_data["base_file"].name) name = slugify(name_base.replace(".","_")) try: # Moved this inside the try/except block because it can raise # exceptions when unicode characters are present. # This should be followed up in upstream Django. tempdir, base_file = form.write_files() saved_layer = save(name, base_file, request.user, overwrite = False, charset = form.cleaned_data["charset"], abstract = form.cleaned_data["abstract"], title = form.cleaned_data["layer_title"], permissions = form.cleaned_data["permissions"], ) except Exception, e: logger.exception(e) out['success'] = False out['errors'] = str(e) else: out['success'] = True out['url'] = reverse('layer_detail', args=[saved_layer.typename]) finally:
def handle(self, **options): ignore_errors = options.get('ignore_errors') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store') if verbosity > 0: console = sys.stdout else: console = None start = datetime.datetime.now() output = gs_slurp(ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace, store=store, filter=filter) updated = [dict_['name'] for dict_ in output if dict_['status']=='updated'] created = [dict_['name'] for dict_ in output if dict_['status']=='created'] failed = [dict_['name'] for dict_ in output if dict_['status']=='failed'] finish = datetime.datetime.now() td = finish - start duration = td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600 duration_rounded = round(duration, 2) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output: if dict_['status'] == 'failed': print "\n\n", dict_['name'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % ( len(output), duration_rounded) print "%d Created layers" % len(created) print "%d Updated layers" % len(updated) print "%d Failed layers" % len(failed) if len(output) > 0: print "%f seconds per layer" % (duration * 1.0 / len(output))
def layer_style_upload(req, layername): user = get_valid_user() ogc_server_settings.DATASTORE = req.user.profile.name def respond(*args,**kw): kw['content_type'] = 'text/html' return json_response(*args,**kw) form = LayerStyleUploadForm(req.POST,req.FILES) if not form.is_valid(): return respond(errors="Please provide an SLD file.") data = form.cleaned_data layer = _resolve_layer(req, layername, 'layers.change_layer',_PERMISSION_MSG_MODIFY) sld = req.FILES['sld'].read() try: dom = etree.XML(sld) except Exception,ex: return respond(errors="The uploaded SLD file is not valid XML")
def handle(self, **options): ignore_errors = options.get("ignore_errors") verbosity = int(options.get("verbosity")) user = options.get("user") owner = get_valid_user(user) workspace = options.get("workspace") if verbosity > 0: console = sys.stdout else: console = None start = datetime.datetime.now() output = gs_slurp(ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace) updated = [dict_["name"] for dict_ in output if dict_["status"] == "updated"] created = [dict_["name"] for dict_ in output if dict_["status"] == "created"] failed = [dict_["name"] for dict_ in output if dict_["status"] == "failed"] finish = datetime.datetime.now() td = finish - start duration = td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600 duration_rounded = round(duration, 2) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output: if dict_["status"] == "failed": print "\n\n", dict_["name"], "\n================" traceback.print_exception(dict_["exception_type"], dict_["error"], dict_["traceback"]) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % (len(output), duration_rounded) print "%d Created layers" % len(created) print "%d Updated layers" % len(updated) print "%d Failed layers" % len(failed) if len(output) > 0: print "%f seconds per layer" % (duration * 1.0 / len(output))
def file_upload(filename, name=None, user=None, title=None, abstract=None, license=None, category=None, keywords=None, regions=None, date=None, skip=True, overwrite=False, charset='UTF-8', is_approved=True, is_published=True, metadata_uploaded_preserve=False, metadata_upload_form=False): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. :return: Uploaded layer :rtype: Layer """ if keywords is None: keywords = [] if regions is None: regions = [] # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') elif not overwrite: name = slugify(name) # assert that name is slugified if license is not None: licenses = License.objects.filter( Q(name__iexact=license) | Q(abbreviation__iexact=license) | Q(url__iexact=license) | Q(description__iexact=license)) if len(licenses) == 1: license = licenses[0] else: license = None if category is not None: try: categories = TopicCategory.objects.filter( Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None except BaseException: pass # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File( f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1, srid = get_bbox(filename) if srid: srid_url = "http://www.spatialreference.org/ref/" + srid.replace(':', '/').lower() + "/" # noqa # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False if not overwrite: if settings.RESOURCE_PUBLISHING or settings.ADMIN_MODERATE_UPLOADS: is_approved = False is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'srid': srid, 'is_approved': is_approved, 'is_published': is_published, 'license': license, 'category': category } # set metadata if 'xml' in files: with open(files['xml']) as f: xml_file = f.read() defaults['metadata_uploaded'] = True defaults['metadata_uploaded_preserve'] = metadata_uploaded_preserve # get model properties from XML identifier, vals, regions, keywords = set_metadata(xml_file) if defaults['metadata_uploaded_preserve']: defaults['metadata_xml'] = xml_file defaults['uuid'] = identifier for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={'description': '', 'gn_description': value}) key = 'category' defaults[key] = value else: defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, 'NLP_ENABLED', False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict({ 'title': defaults.get('title', None), 'abstract': defaults.get('abstract', None), 'purpose': defaults.get('purpose', None)}) if nlp_metadata: regions_resolved.extend(nlp_metadata.get('regions', [])) keywords.extend(nlp_metadata.get('keywords', [])) except BaseException: logger.error("NLP extraction failed.") # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. created = False layer = None with transaction.atomic(): try: if overwrite: try: layer = Layer.objects.get(name=valid_name) except Layer.DoesNotExist: layer = None if not layer: if not metadata_upload_form: layer, created = Layer.objects.get_or_create( name=valid_name, workspace=settings.DEFAULT_WORKSPACE, defaults=defaults ) elif identifier: layer, created = Layer.objects.get_or_create( uuid=identifier, defaults=defaults ) except BaseException: raise # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: # update with new information defaults['upload_session'] = upload_session defaults['title'] = defaults.get('title', None) or layer.title defaults['abstract'] = defaults.get('abstract', None) or layer.abstract defaults['bbox_x0'] = defaults.get('bbox_x0', None) or layer.bbox_x0 defaults['bbox_x1'] = defaults.get('bbox_x1', None) or layer.bbox_x1 defaults['bbox_y0'] = defaults.get('bbox_y0', None) or layer.bbox_y0 defaults['bbox_y1'] = defaults.get('bbox_y1', None) or layer.bbox_y1 defaults['is_approved'] = defaults.get( 'is_approved', is_approved) or layer.is_approved defaults['is_published'] = defaults.get( 'is_published', is_published) or layer.is_published defaults['license'] = defaults.get('license', None) or layer.license defaults['category'] = defaults.get('category', None) or layer.category try: Layer.objects.filter(id=layer.id).update(**defaults) layer.refresh_from_db() except Layer.DoesNotExist: import traceback tb = traceback.format_exc() logger.error(tb) raise # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite # Blank out the store if overwrite is true. # geoserver_post_save_signal should upload the new file if needed layer.store = '' if overwrite else layer.store layer.save() if upload_session: upload_session.resource = layer upload_session.processed = True upload_session.save() # set SLD # if 'sld' in files: # sld = None # with open(files['sld']) as f: # sld = f.read() # if sld: # set_layer_style(layer, layer.alternate, sld, base_file=files['sld']) # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: if not layer.keywords: layer.keywords = keywords else: layer.keywords.add(*keywords) # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: if not layer.regions: layer.regions = regions_resolved else: layer.regions.clear() layer.regions.add(*regions_resolved) # Assign and save the charset using the Layer class' object (layer) if charset != 'UTF-8': layer.charset = charset layer.save() to_update = {} if defaults.get('title', title) is not None: to_update['title'] = defaults.get('title', title) if defaults.get('abstract', abstract) is not None: to_update['abstract'] = defaults.get('abstract', abstract) if defaults.get('date', date) is not None: to_update['date'] = defaults.get('date', datetime.strptime(date, '%Y-%m-%d %H:%M:%S') if date else None) if defaults.get('license', license) is not None: to_update['license'] = defaults.get('license', license) if defaults.get('category', category) is not None: to_update['category'] = defaults.get('category', category) # Update ResourceBase if not to_update: pass else: try: ResourceBase.objects.filter( id=layer.resourcebase_ptr.id).update( **to_update) Layer.objects.filter(id=layer.id).update(**to_update) # Refresh from DB layer.refresh_from_db() except BaseException: import traceback tb = traceback.format_exc() logger.error(tb) return layer
def test_layer_permissions(self): try: # Test permissions on a layer # grab bobby bobby = get_user_model().objects.get(username="******") layers = Layer.objects.all()[:2].values_list('id', flat=True) test_perm_layer = Layer.objects.get(id=layers[0]) thefile = os.path.join(gisdata.VECTOR_DATA, 'san_andres_y_providencia_poi.shp') layer = geoserver_upload(test_perm_layer, thefile, bobby, 'san_andres_y_providencia_poi', overwrite=True) self.assertIsNotNone(layer) _log( " ------------------------------------------------------------- " ) _log(layer) _log( " ------------------------------------------------------------- " ) # Reset GeoFence Rules purge_geofence_all() geofence_rules_count = get_geofence_rules_count() self.assertTrue(geofence_rules_count == 0) ignore_errors = False skip_unadvertised = False skip_geonode_registered = False remove_deleted = True verbosity = 2 owner = get_valid_user('admin') workspace = 'geonode' filter = None store = None permissions = {'users': {"admin": ['change_layer_data']}} gs_slurp(ignore_errors, verbosity=verbosity, owner=owner, console=StreamToLogger(logger, logging.INFO), workspace=workspace, store=store, filter=filter, skip_unadvertised=skip_unadvertised, skip_geonode_registered=skip_geonode_registered, remove_deleted=remove_deleted, permissions=permissions, execute_signals=True) layer = Layer.objects.get(title='san_andres_y_providencia_poi') check_layer(layer) geofence_rules_count = get_geofence_rules_count() _log("0. geofence_rules_count: %s " % geofence_rules_count) self.assertEquals(geofence_rules_count, 2) # Set the layer private for not authenticated users layer.set_permissions({'users': {'AnonymousUser': []}}) url = 'http://localhost:8080/geoserver/geonode/ows?' \ 'LAYERS=geonode%3Asan_andres_y_providencia_poi&STYLES=' \ '&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap' \ '&SRS=EPSG%3A4326' \ '&BBOX=-81.394599749999,13.316009005566,' \ '-81.370560451855,13.372728455566' \ '&WIDTH=217&HEIGHT=512' # test view_resourcebase permission on anonymous user request = urllib2.Request(url) response = urllib2.urlopen(request) self.assertTrue(response.info().getheader('Content-Type'), 'application/vnd.ogc.se_xml;charset=UTF-8') # test WMS with authenticated user that has not view_resourcebase: # the layer must be not accessible (response is xml) request = urllib2.Request(url) base64string = base64.encodestring( '%s:%s' % ('bobby', 'bob')).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string) response = urllib2.urlopen(request) self.assertTrue(response.info().getheader('Content-Type'), 'application/vnd.ogc.se_xml;charset=UTF-8') # test WMS with authenticated user that has view_resourcebase: the layer # must be accessible (response is image) assign_perm('view_resourcebase', bobby, layer.get_self_resource()) request = urllib2.Request(url) base64string = base64.encodestring( '%s:%s' % ('bobby', 'bob')).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string) response = urllib2.urlopen(request) self.assertTrue(response.info().getheader('Content-Type'), 'image/png') # test change_layer_data # would be nice to make a WFS/T request and test results, but this # would work only on PostGIS layers # test change_layer_style url = 'http://localhost:8000/gs/rest/workspaces/geonode/styles/san_andres_y_providencia_poi.xml' sld = """<?xml version="1.0" encoding="UTF-8"?> <sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> <sld:NamedLayer> <sld:Name>geonode:san_andres_y_providencia_poi</sld:Name> <sld:UserStyle> <sld:Name>san_andres_y_providencia_poi</sld:Name> <sld:Title>san_andres_y_providencia_poi</sld:Title> <sld:IsDefault>1</sld:IsDefault> <sld:FeatureTypeStyle> <sld:Rule> <sld:PointSymbolizer> <sld:Graphic> <sld:Mark> <sld:Fill> <sld:CssParameter name="fill">#8A7700 </sld:CssParameter> </sld:Fill> <sld:Stroke> <sld:CssParameter name="stroke">#bbffff </sld:CssParameter> </sld:Stroke> </sld:Mark> <sld:Size>10</sld:Size> </sld:Graphic> </sld:PointSymbolizer> </sld:Rule> </sld:FeatureTypeStyle> </sld:UserStyle> </sld:NamedLayer> </sld:StyledLayerDescriptor>""" # user without change_layer_style cannot edit it self.assertTrue(self.client.login(username='******', password='******')) response = self.client.put( url, sld, content_type='application/vnd.ogc.sld+xml') self.assertEquals(response.status_code, 401) # user with change_layer_style can edit it assign_perm('change_layer_style', bobby, layer) perm_spec = { 'users': { 'bobby': [ 'view_resourcebase', 'change_resourcebase', ] } } layer.set_permissions(perm_spec) response = self.client.get(url) self.assertEquals(response.status_code, 200) response = self.client.put( url, sld, content_type='application/vnd.ogc.sld+xml') finally: try: layer.delete() except BaseException: pass
def handle(self, **options): ignore_errors = options.get('ignore_errors') skip_unadvertised = options.get('skip_unadvertised') skip_geonode_registered = options.get('skip_geonode_registered') remove_deleted = options.get('remove_deleted') verbosity = int(options.get('verbosity')) user = options.get('user') owner = get_valid_user(user) workspace = options.get('workspace') filter = options.get('filter') store = options.get('store') if not options.get('permissions'): permissions = None else: permissions = ast.literal_eval(options.get('permissions')) if verbosity > 0: console = sys.stdout else: console = None output = gs_slurp( ignore_errors, verbosity=verbosity, owner=owner, console=console, workspace=workspace, store=store, filter=filter, skip_unadvertised=skip_unadvertised, skip_geonode_registered=skip_geonode_registered, remove_deleted=remove_deleted, permissions=permissions, execute_signals=True) if verbosity > 1: print("\nDetailed report of failures:") for dict_ in output['layers']: if dict_['status'] == 'failed': print("\n\n", dict_['name'], "\n================") traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if remove_deleted: print("Detailed report of layers to be deleted from GeoNode that failed:") for dict_ in output['deleted_layers']: if dict_['status'] == 'delete_failed': print("\n\n", dict_['name'], "\n================") traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print("\n\nFinished processing {} layers in {} seconds.\n".format( len(output['layers']), round(output['stats']['duration_sec'], 2))) print("{} Created layers".format(output['stats']['created'])) print("{} Updated layers".format(output['stats']['updated'])) print("{} Failed layers".format(output['stats']['failed'])) try: duration_layer = round( output['stats']['duration_sec'] * 1.0 / len(output['layers']), 2) except ZeroDivisionError: duration_layer = 0 if len(output) > 0: print("{} seconds per layer".format(duration_layer)) if remove_deleted: print("\n{} Deleted layers".format(output['stats']['deleted']))
def file_upload(filename, name=None, user=None, title=None, abstract=None, keywords=[], category=None, regions=[], skip=True, overwrite=False, charset='UTF-8', main_id=None, form_metadata=None): #^^ """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') if category is not None: categories = TopicCategory.objects.filter(Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: if main_id != None: #^^ layerfile = LayerFile( #^^ upload_session=upload_session, #^^ name=type_name, #^^ file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name)) #^^ ) #^^ layerfile.main_id = main_id #^^ layerfile.save() #^^ else: #^^ upload_session.layerfile_set.create(name=type_name, file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_published': is_published, 'category': category } #^^ start processing xml metadata file before form metadata fields, moved up here xml_metadata_created = None #^^ # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, regions, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={'description': '', 'gn_description': value}) key = 'category' defaults[key] = value else: if key == 'date': #^^ print 'skipping date xml metadata' #^^ xml_metadata_created = value #^^ else: #^^ defaults[key] = value #^^ end #^^ start processing layer metadata metadata = None if form_metadata != None: print 'debug form_metadata' print form_metadata metadata = json.loads(form_metadata) # check if owner exists if (metadata['owner'].isdigit()): try: owner = get_user_model().objects.get(id=metadata['owner']) defaults['owner'] = owner except get_user_model().DoesNotExist: pass defaults['title'] = metadata['title'] # parse date format from datetimepicker YYYY-MM-DD HH:MM:SS if (len(metadata['date'])): try: parse(metadata['date']) defaults['date'] = metadata['date'] except ValueError: pass defaults['date_type'] = metadata['date_type'] defaults['edition'] = metadata['edition'] defaults['abstract'] = metadata['abstract'] defaults['purpose'] = metadata['purpose'] defaults['maintenance_frequency'] = metadata['maintenance_frequency'] try: defaults['restriction_code_type'] = RestrictionCodeType(id=metadata['restriction_code_type']) except: pass defaults['constraints_other'] = metadata['constraints_other'] try: defaults['license'] = License(id=metadata['license']) except: pass defaults['language'] = metadata['language'] try: defaults['spatial_representation_type'] = SpatialRepresentationType(id=metadata['spatial_representation_type']) except: pass if (len(metadata['temporal_extent_start'])): try: parse(metadata['temporal_extent_start']) defaults['temporal_extent_start'] = metadata['temporal_extent_start'] except ValueError: pass if (len(metadata['temporal_extent_end'])): try: parse(metadata['temporal_extent_end']) defaults['temporal_extent_end'] = metadata['temporal_extent_end'] except ValueError: pass defaults['supplemental_information'] = metadata['supplemental_information'] defaults['distribution_url'] = metadata['distribution_url'] defaults['distribution_description'] = metadata['distribution_description'] defaults['data_quality_statement'] = metadata['data_quality_statement'] if (metadata['featured'] != False): defaults['featured'] = True if (metadata['is_published'] != False): defaults['is_published'] = True # make sure thumbnail URL is valid link to an image if (len(metadata['thumbnail_url'])): val = URLValidator() try: thumbnail_url = metadata['thumbnail_url'] val(thumbnail_url) if (thumbnail_url.lower().startswith(('http://', 'https://')) and thumbnail_url.lower().endswith(('.jpg', '.jpeg', '.png'))): print 'debug thumbnail_url' print thumbnail_url defaults['thumbnail_url'] = thumbnail_url except ValidationError: pass if (len(metadata['keywords'])): keywords = [keyword.strip() for keyword in metadata['keywords'].split(',')] if (len(metadata['regions'])): regions_id = metadata['regions'].split(',') for region_id in regions_id: try: region = Region.objects.get(id=region_id) # store region code to be resolved below in resolve_regions() regions.append(region.code) except Region.DoesNotExist: pass try: defaults['category'] = TopicCategory(id=metadata['category_choice_field']) except: pass #^^ end processing layer metadata #^^ moved before processing form metadata fields """ # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, regions, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={'description': '', 'gn_description': value}) key = 'category' defaults[key] = value else: defaults[key] = value """ #^^ regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, 'NLP_ENABLED', False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict({ 'title': defaults.get('title', None), 'abstract': defaults.get('abstract', None), 'purpose': defaults.get('purpose', None)}) if nlp_metadata: regions_resolved.extend(nlp_metadata.get('regions', [])) keywords.extend(nlp_metadata.get('keywords', [])) except: print "NLP extraction failed." # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create( name=valid_name, defaults=defaults ) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: layer.keywords.add(*keywords) #^^ start saving metadata point of contact, layer needs to exist first if form_metadata != None and metadata['poc'].isdigit(): try: contact = get_user_model().objects.get(id=metadata['poc']) layer.poc = contact layer.save() except get_user_model().DoesNotExist: pass #^^ end #^^ start saving metadata author, layer needs to exist first if form_metadata != None and metadata['metadata_author'].isdigit(): try: author = get_user_model().objects.get(id=metadata['metadata_author']) layer.metadata_author = author layer.save() except get_user_model().DoesNotExist: pass #^^ end #^^ start saving icraf_dr_main's Layer reference key if main_id != None: try: main = Main.objects.get(id=main_id) main.layer = layer if xml_metadata_created: main.date_created = xml_metadata_created main.save() except: pass #^^ end # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: layer.regions.add(*regions_resolved) #^^ start send email notification to 'Pengelola Basis Data' group managers if 'notification' in settings.INSTALLED_APPS: try: group_approver = GroupProfile.objects.get(title='Pengelola Basis Data') if group_approver: group_managers = group_approver.get_managers() if group_managers: print 'debug group_approver.title' print group_approver.title print group_managers notif_ctx = { 'resource': layer, } print 'sending notification' notification.send(group_managers, 'layer_created', notif_ctx) except: pass #^^ end return layer
def handle(self, url, name, type, method, console=sys.stdout, **options): user = options.get('user') owner = get_valid_user(user) register_layers = options.get('registerlayers') username = options.get('username') password = options.get('password') perm_spec = options.get('permspec') register_service = True # First Check if this service already exists based on the URL base_url = url try: service = Service.objects.get(base_url=base_url) except Service.DoesNotExist: service = None if service is not None: print "This is an existing Service" register_service = False # Then Check that the name is Unique try: service = Service.objects.get(name=name) except Service.DoesNotExist: service = None if service is not None: print "This is an existing service using this name.\nPlease specify a different name." if register_service: if method == 'C': response = _register_cascaded_service(type, url, name, username, password, owner=owner, verbosity=True) elif method == 'I': response = _register_indexed_service(type, url, name, username, password, owner=owner, verbosity=True) elif method == 'H': response = _register_harvested_service(url, name, username, password, owner=owner, verbosity=True) elif method == 'X': print 'Not Implemented (Yet)' elif method == 'L': print 'Local Services not configurable via API' else: print 'Invalid method' json_response = json.loads(response.content) if "id" in json_response: print "Service created with id of %d" % json_response["id"] service = Service.objects.get(id=json_response["id"]) else: print "Something went wrong: %s" % response.content return print service.id print register_layers if service and register_layers: layers=[] for layer in service.servicelayer_set.all(): layers.append(layer.typename) if service.method == 'C': response = _register_cascaded_layers(user, service, layers, perm_spec) elif service.method == 'I': response = _register_indexed_layers(user, service, layers, perm_spec) elif service.method == 'X': print 'Not Implemented (Yet)' elif service.method == 'L': print 'Local Services not configurable via API' else: print('Invalid Service Type') print response.content
def handle(self, *args, **options): verbosity = int(options.get('verbosity')) # ignore_errors = options.get('ignore_errors') username = options.get('user') user = get_valid_user(username) overwrite = options.get('overwrite') name = options.get('layername', None) title = options.get('title', None) abstract = options.get('abstract', None) date = options.get('date', None) license = options.get('license', None) category = options.get('category', None) private = options.get('private', False) metadata_uploaded_preserve = options.get('metadata_uploaded_preserve', False) charset = options.get('charset', 'UTF-8') if verbosity > 0: console = self.stdout else: console = None skip = not overwrite keywords = options.get('keywords').split(',') if len(keywords) == 1 and keywords[0] == '': keywords = [] else: keywords = [k.strip() for k in keywords] regions = options.get('regions').split(',') if len(regions) == 1 and regions[0] == '': regions = [] else: regions = [r.strip() for r in regions] start = datetime.datetime.now(timezone.get_current_timezone()) output = [] for path in options['path']: out = upload(path, user=user, overwrite=overwrite, skip=skip, name=name, title=title, abstract=abstract, date=date, keywords=keywords, verbosity=verbosity, console=console, license=license, category=category, regions=regions, private=private, metadata_uploaded_preserve=metadata_uploaded_preserve, charset=charset) output.extend(out) updated = [ dict_['file'] for dict_ in output if dict_['status'] == 'updated' ] created = [ dict_['file'] for dict_ in output if dict_['status'] == 'created' ] skipped = [ dict_['file'] for dict_ in output if dict_['status'] == 'skipped' ] failed = [ dict_['file'] for dict_ in output if dict_['status'] == 'failed' ] finish = datetime.datetime.now(timezone.get_current_timezone()) td = finish - start duration = td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600 duration_rounded = round(duration, 2) if verbosity > 1: print("\nDetailed report of failures:") for dict_ in output: if dict_['status'] == 'failed': print("\n\n", dict_['file'], "\n================") traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print("\n\nFinished processing {} layers in {} seconds.\n".format( len(output), duration_rounded)) print("{} Created layers".format(len(created))) print("{} Updated layers".format(len(updated))) print("{} Skipped layers".format(len(skipped))) print("{} Failed layers".format(len(failed))) if len(output) > 0: print("{} seconds per layer".format(duration * 1.0 / len(output)))
def file_upload(filename, name=None, user=None, title=None, abstract=None, keywords=[], category=None, regions=[], date=None, skip=True, overwrite=False, charset='UTF-8', metadata_uploaded_preserve=False): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') if category is not None: categories = TopicCategory.objects.filter( Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_published': is_published, 'category': category } # set metadata if 'xml' in files: with open(files['xml']) as f: xml_file = f.read() defaults['metadata_uploaded'] = True defaults['metadata_uploaded_preserve'] = metadata_uploaded_preserve # get model properties from XML identifier, vals, regions, keywords = set_metadata(xml_file) if defaults['metadata_uploaded_preserve']: defaults['metadata_xml'] = xml_file defaults['uuid'] = identifier for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={ 'description': '', 'gn_description': value }) key = 'category' defaults[key] = value else: defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, 'NLP_ENABLED', False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict({ 'title': defaults.get('title', None), 'abstract': defaults.get('abstract', None), 'purpose': defaults.get('purpose', None) }) if nlp_metadata: regions_resolved.extend(nlp_metadata.get('regions', [])) keywords.extend(nlp_metadata.get('keywords', [])) except: print "NLP extraction failed." # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create(name=valid_name, defaults=defaults) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: layer.keywords.add(*keywords) # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: layer.regions.add(*regions_resolved) if date is not None: layer.date = datetime.strptime(date, '%Y-%m-%d %H:%M:%S') layer.save() return layer
def handle(self, url, name, type, method, console=sys.stdout, **options): user = options.get('user') owner = get_valid_user(user) limit = options.get('limit') register_service = True # First Check if this service already exists based on the URL base_url = url try: service = Service.objects.get(base_url=base_url) except Service.DoesNotExist: service = None if service is not None: print("This is an existing Service") register_service = False # Then Check that the name is Unique try: service = Service.objects.get(name=name) except Service.DoesNotExist: service = None if service is not None: print("This is an existing service using this name.\n" "Please specify a different name.") if register_service: if method == 'I': form = ExchangeCreateServiceForm(data={ 'url': base_url, 'type': type }) if form.is_valid(): service_handler = form.cleaned_data["service_handler"] service = service_handler.create_geonode_service( owner=owner ) service.full_clean() service.save() service.keywords.add(*service_handler.get_keywords()) service.set_default_permissions() service_handler = get_service_handler( service.base_url, service.type ) available_resources = service_handler.get_resources() print("Service created with id of %d" % service.id) print(" Harvesting...") processed = 0 for resource in available_resources: if processed < limit: try: service_handler.harvest_resource( resource.id, service ) processed = processed + 1 except: print(" - Failed Harvesting Resource Id: {}" .format(resource.id)) else: break else: print(form.errors) else: print("Indexing is only available.") print('Done')
def file_upload(filename, name=None, creator=None, title=None, abstract=None, skip=True, overwrite=False, keywords=[], charset='UTF-8', layer_type=None, owner=None): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(creator) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Add them to the upload session (new file fields are created). for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create(name=type_name, file=File(f)) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) defaults = { 'layer_type': layer_type, 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': owner or creator, 'creator': creator, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, } # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), gn_description=value) key = 'category' else: defaults[key] = value # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create( name=valid_name, defaults=defaults ) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session layer.save() # Assign the keywords (needs to be done after saving) if len(keywords) > 0: layer.keywords.add(*keywords) return layer
def layer_style_manage(req, layername): user = get_valid_user() ogc_server_settings.DATASTORE = req.user.profile.name layer = _resolve_layer(req, layername, 'layers.change_layer',_PERMISSION_MSG_MODIFY) if req.method == 'GET': try: cat = Layer.objects.gs_catalog # First update the layer style info from GS to GeoNode's DB set_styles(layer, cat) all_available_gs_styles = cat.get_styles() gs_styles = [] for style in all_available_gs_styles: gs_styles.append(style.name) current_layer_styles = layer.styles.all() layer_styles = [] for style in current_layer_styles: layer_styles.append(style.name) # Render the form return render_to_response( 'layers/layer_style_manage.html', RequestContext(req, { "layer": layer, "gs_styles": gs_styles, "layer_styles": layer_styles, "default_style": layer.default_style.name } ) ) except (FailedRequestError, EnvironmentError) as e: msg = ('Could not connect to geoserver at "%s"' 'to manage style information for layer "%s"' % ( ogc_server_settings.LOCATION, layer.name) ) logger.warn(msg, e) # If geoserver is not online, return an error return render_to_response( 'layers/layer_style_manage.html', RequestContext(req, { "layer": layer, "error": msg } ) ) elif req.method == 'POST': try: selected_styles = req.POST.getlist('style-select') default_style = req.POST['default_style'] # Save to GeoServer cat = Layer.objects.gs_catalog gs_layer = cat.get_layer(layer.name) gs_layer.default_style = default_style styles = [] for style in selected_styles: styles.append(type('style',(object,),{'name' : style})) gs_layer.styles = styles cat.save(gs_layer) # Save to Django layer = set_styles(layer, cat) layer.save() return HttpResponseRedirect(reverse('layer_detail', args=(layer.typename,))) except (FailedRequestError, EnvironmentError, MultiValueDictKeyError) as e: msg = ('Error Saving Styles for Layer "%s"' % (layer.name) ) logger.warn(msg, e) return render_to_response( 'layers/layer_style_manage.html', RequestContext(req, { "layer": layer, "error": msg } ) )
def file_upload(filename, name=None, user=None, title=None, abstract=None, style_name=None, skip=True, overwrite=False, keywords=[], charset='UTF-8', category=None, date=None): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') if category is not None: category = TopicCategory.objects.get(identifier=category) # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_published': is_published, 'category': category } # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={ 'description': '', 'gn_description': value }) key = 'category' defaults[key] = value else: defaults[key] = value # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create(name=valid_name, defaults=defaults) # set layer style in geoserver if style_name is not None: # import here because import at top of file fails for some reason from geonode.geoserver.helpers import gs_catalog try: gs_style = gs_catalog.get_style(style_name) except: gs_style = None if gs_style is not None: gs_layer = gs_catalog.get_layer(layer.name) gs_layer.default_style = gs_style gs_catalog.save(gs_layer) # set layer date if date is not None: layer.date = date # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) if len(keywords) > 0: layer.keywords.add(*keywords) return layer
def handle(self, *args, **options): verbosity = int(options.get('verbosity')) # ignore_errors = options.get('ignore_errors') username = options.get('user') user = get_valid_user(username) overwrite = options.get('overwrite') category = options.get('category', None) private = options.get('private', False) title = options.get('title', None) date = options.get('date', None) metadata_uploaded_preserve = options.get('metadata_uploaded_preserve', False) if verbosity > 0: console = self.stdout else: console = None if overwrite: skip = False else: skip = True keywords = options.get('keywords').split(',') if len(keywords) == 1 and keywords[0] == '': keywords = [] else: keywords = map(str.strip, keywords) regions = options.get('regions').split(',') if len(regions) == 1 and regions[0] == '': regions = [] else: regions = map(str.strip, regions) start = datetime.datetime.now() output = [] for path in args: out = upload( path, user=user, overwrite=overwrite, skip=skip, keywords=keywords, verbosity=verbosity, console=console, category=category, regions=regions, title=title, date=date, private=private, metadata_uploaded_preserve=metadata_uploaded_preserve) output.extend(out) updated = [dict_['file'] for dict_ in output if dict_['status'] == 'updated'] created = [dict_['file'] for dict_ in output if dict_['status'] == 'created'] skipped = [dict_['file'] for dict_ in output if dict_['status'] == 'skipped'] failed = [dict_['file'] for dict_ in output if dict_['status'] == 'failed'] finish = datetime.datetime.now() td = finish - start duration = td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600 duration_rounded = round(duration, 2) if verbosity > 1: print "\nDetailed report of failures:" for dict_ in output: if dict_['status'] == 'failed': print "\n\n", dict_['file'], "\n================" traceback.print_exception(dict_['exception_type'], dict_['error'], dict_['traceback']) if verbosity > 0: print "\n\nFinished processing %d layers in %s seconds.\n" % ( len(output), duration_rounded) print "%d Created layers" % len(created) print "%d Updated layers" % len(updated) print "%d Skipped layers" % len(skipped) print "%d Failed layers" % len(failed) if len(output) > 0: print "%f seconds per layer" % (duration * 1.0 / len(output))
def publish_resource_geonode(store, resource_name, workspace_name='geonode', execute_signals=True, user="******", verbosity=1, permissions=None, ignore_errors=True): output = { 'stats': { 'failed': 0, 'updated': 0, 'created': 0, 'deleted': 0, }, 'layers': [], 'deleted_layers': [] } cat = gs_catalog owner = get_valid_user(user) workspace = cat.get_workspace(workspace_name) store = get_store(cat, store, workspace=workspace) if store is None: rsc = [] else: resources = cat.get_resources(stores=[store]) rsc = [k for k in resources if '%s' % (k.name) in resource_name] for resource in rsc: name = resource.name the_store = resource.store workspace = the_store.workspace try: layer, created = Layer.objects.get_or_create( name=name, workspace=workspace.name, defaults={ # "workspace": workspace.name, "store": the_store.name, "storeType": the_store.resource_type, "alternate": "%s:%s" % (workspace.name, resource.name), "title": resource.title or 'No title provided', "abstract": resource.abstract or u"{}".format(_('No abstract provided')), "owner": owner, "uuid": str(uuid.uuid4()) }) # print("laayer", layer) # print("created", created) layer.bbox_x0 = Decimal(resource.native_bbox[0]) layer.bbox_x1 = Decimal(resource.native_bbox[1]) layer.bbox_y0 = Decimal(resource.native_bbox[2]) layer.bbox_y1 = Decimal(resource.native_bbox[3]) layer.srid = resource.projection # sync permissions in GeoFence perm_spec = json.loads(_perms_info_json(layer)) layer.set_permissions(perm_spec) # recalculate the layer statistics set_attributes_from_geoserver(layer, overwrite=True) # in some cases we need to explicitily save the resource to execute the signals # (for sure when running updatelayers) if execute_signals: layer.save() # Fix metadata links if the ip has changed if layer.link_set.metadata().count() > 0: if not created and settings.SITEURL not in layer.link_set.metadata( )[0].url: layer.link_set.metadata().delete() layer.save() metadata_links = [] for link in layer.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) resource.metadata_links = metadata_links cat.save(resource) except Exception as e: print("ERROR: ", e) if ignore_errors: status = 'failed' exception_type, error, traceback = sys.exc_info() else: if verbosity > 0: msg = "Stopping process because --ignore-errors was not set and an error was found." print(msg, file=sys.stderr) raise_( Exception, Exception("Failed to process {}".format(resource.name), e), sys.exc_info()[2]) else: if created: if not permissions: layer.set_default_permissions() else: layer.set_permissions(permissions) status = 'created' output['stats']['created'] += 1 else: status = 'updated' output['stats']['updated'] += 1
def handle(self, url, name, type, method, console=sys.stdout, **options): user = options.get('user') owner = get_valid_user(user) register_layers = options.get('registerlayers') username = options.get('username') password = options.get('password') perm_spec = options.get('permspec') register_service = True # First Check if this service already exists based on the URL base_url = url try: service = Service.objects.get(base_url=base_url) except Service.DoesNotExist: service = None if service is not None: print("This is an existing Service") register_service = False # Then Check that the name is Unique try: service = Service.objects.get(name=name) except Service.DoesNotExist: service = None if service is not None: print( "This is an existing service using this name.\nPlease specify a different name." ) if register_service: if method == 'C': response = _register_cascaded_service(type, url, name, username, password, owner=owner, verbosity=True) elif method == 'I': response = _register_indexed_service(type, url, name, username, password, owner=owner, verbosity=True) elif method == 'H': response = _register_harvested_service(url, name, username, password, owner=owner, verbosity=True) elif method == 'X': print("Not Implemented (Yet)") elif method == 'L': print("Local Services not configurable via API") else: print("Invalid method") json_response = json.loads(response.content) if "id" in json_response: print("Service created with id of {}".format( json_response["id"])) service = Service.objects.get(id=json_response["id"]) else: print("Something went wrong: {}".format(response.content)) return print(service.id) print(register_layers) if service and register_layers: layers = [] for layer in service.layer_set.all(): layers.append(layer.alternate) if service.method == 'C': response = _register_cascaded_layers(user, service, layers, perm_spec) elif service.method == 'I': response = _register_indexed_layers(user, service, layers, perm_spec) elif service.method == 'X': print("Not Implemented (Yet)") elif service.method == 'L': print("Local Services not configurable via API") else: print("Invalid Service Type") print(response.content)
def file_upload(filename, name=None, user=None, title=None, abstract=None, license=None, category=None, keywords=None, regions=None, date=None, skip=True, overwrite=False, charset='UTF-8', metadata_uploaded_preserve=False, metadata_upload_form=False): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. :return: Uploaded layer :rtype: Layer """ if keywords is None: keywords = [] if regions is None: regions = [] # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') else: name = slugify(name) # assert that name is slugified if license is not None: licenses = License.objects.filter( Q(name__iexact=license) | Q(abbreviation__iexact=license) | Q(url__iexact=license) | Q(description__iexact=license)) if len(licenses) == 1: license = licenses[0] else: license = None if category is not None: categories = TopicCategory.objects.filter( Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File( f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_approved = True is_published = True if settings.RESOURCE_PUBLISHING or settings.ADMIN_MODERATE_UPLOADS: is_approved = False is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_approved': is_approved, 'is_published': is_published, 'license': license, 'category': category } # set metadata if 'xml' in files: with open(files['xml']) as f: xml_file = f.read() defaults['metadata_uploaded'] = True defaults['metadata_uploaded_preserve'] = metadata_uploaded_preserve # get model properties from XML identifier, vals, regions, keywords = set_metadata(xml_file) if defaults['metadata_uploaded_preserve']: defaults['metadata_xml'] = xml_file defaults['uuid'] = identifier for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={'description': '', 'gn_description': value}) key = 'category' defaults[key] = value else: defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, 'NLP_ENABLED', False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict({ 'title': defaults.get('title', None), 'abstract': defaults.get('abstract', None), 'purpose': defaults.get('purpose', None)}) if nlp_metadata: regions_resolved.extend(nlp_metadata.get('regions', [])) keywords.extend(nlp_metadata.get('keywords', [])) except BaseException: print "NLP extraction failed." # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. created = False layer = None with transaction.atomic(): if not metadata_upload_form: layer, created = Layer.objects.get_or_create( name=valid_name, defaults=defaults ) elif identifier: layer, created = Layer.objects.get_or_create( uuid=identifier, defaults=defaults ) else: layer = Layer.objects.get(alternate=title) created = False overwrite = True # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: if layer.upload_session: layer.upload_session.layerfile_set.all().delete() if upload_session: layer.upload_session = upload_session # update with new information db_layer = Layer.objects.filter(id=layer.id) defaults['upload_session'] = upload_session defaults['title'] = defaults.get('title', None) or layer.title defaults['abstract'] = defaults.get('abstract', None) or layer.abstract defaults['bbox_x0'] = defaults.get('bbox_x0', None) or layer.bbox_x0 defaults['bbox_x1'] = defaults.get('bbox_x1', None) or layer.bbox_x1 defaults['bbox_y0'] = defaults.get('bbox_y0', None) or layer.bbox_y0 defaults['bbox_y1'] = defaults.get('bbox_y1', None) or layer.bbox_y1 defaults['is_approved'] = defaults.get('is_approved', None) or layer.is_approved defaults['is_published'] = defaults.get('is_published', None) or layer.is_published defaults['license'] = defaults.get('license', None) or layer.license defaults['category'] = defaults.get('category', None) or layer.category db_layer.update(**defaults) layer.refresh_from_db() # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite # Blank out the store if overwrite is true. # geoserver_post_save_signal should upload the new file if needed layer.store = '' layer.save() # set SLD # if 'sld' in files: # sld = None # with open(files['sld']) as f: # sld = f.read() # if sld: # set_layer_style(layer, layer.alternate, sld, base_file=files['sld']) # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: if not layer.keywords: layer.keywords = keywords else: layer.keywords.add(*keywords) # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: if not layer.regions: layer.regions = regions_resolved else: layer.regions.clear() layer.regions.add(*regions_resolved) # Assign and save the charset using the Layer class' object (layer) if charset != 'UTF-8': layer.charset = charset layer.save() to_update = {} if defaults.get('title', title) is not None: to_update['title'] = defaults.get('title', title) if defaults.get('abstract', abstract) is not None: to_update['abstract'] = defaults.get('abstract', abstract) if defaults.get('date', date) is not None: to_update['date'] = defaults.get('date', datetime.strptime(date, '%Y-%m-%d %H:%M:%S') if date else None) if defaults.get('license', license) is not None: to_update['license'] = defaults.get('license', license) if defaults.get('category', category) is not None: to_update['category'] = defaults.get('category', category) # Update ResourceBase if not to_update: pass else: ResourceBase.objects.filter( id=layer.resourcebase_ptr.id).update( **to_update) Layer.objects.filter(id=layer.id).update(**to_update) # Refresh from DB layer.refresh_from_db() return layer
def file_upload(filename, layer=None, gtype=None, name=None, user=None, title=None, abstract=None, license=None, category=None, keywords=None, regions=None, date=None, skip=True, overwrite=False, charset='UTF-8', is_approved=True, is_published=True, metadata_uploaded_preserve=False, metadata_upload_form=False): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. :return: Uploaded layer :rtype: Layer """ if keywords is None: keywords = [] if regions is None: regions = [] # Get a valid user theuser = get_valid_user(user) # Create a new upload session if layer: latest_uploads = UploadSession.objects.filter( resource=layer).order_by('-date') if latest_uploads.count() > 1: upload_session = latest_uploads.first() else: upload_session, _created = UploadSession.objects.get_or_create( resource=layer) upload_session.user = theuser upload_session.layerfile_set.all().delete() else: upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer if os.path.exists(filename): files = get_files(filename) else: raise Exception( _("You are attempting to replace a vector layer with an unknown format." )) # We are going to replace an existing Layer... if layer and overwrite: validate_input_source(layer, filename, files, gtype, action_type='replace') # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') elif not overwrite: name = slugify(name) # assert that name is slugified if license is not None: licenses = License.objects.filter( Q(name__iexact=license) | Q(abbreviation__iexact=license) | Q(url__iexact=license) | Q(description__iexact=license)) if len(licenses) == 1: license = licenses[0] else: license = None if category is not None: try: categories = TopicCategory.objects.filter( Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None except Exception: pass # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name=f'{assigned_name or valid_name}.{type_name}')) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box *bbox, srid = get_bbox(filename) bbox_polygon = BBOXHelper.from_xy(bbox).as_polygon() if srid: srid_url = f"http://www.spatialreference.org/ref/{srid.replace(':', '/').lower()}/" # noqa bbox_polygon.srid = int(srid.split(':')[1]) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False if not overwrite: if settings.RESOURCE_PUBLISHING: is_published = False if settings.ADMIN_MODERATE_UPLOADS: is_approved = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_polygon': bbox_polygon, 'srid': 'EPSG:4326', 'is_approved': is_approved, 'is_published': is_published, 'license': license, 'category': category } # set metadata if 'xml' in files: with open(files['xml']) as f: xml_file = f.read() defaults['metadata_uploaded'] = True defaults['metadata_uploaded_preserve'] = metadata_uploaded_preserve # get model properties from XML identifier, vals, regions, keywords = set_metadata(xml_file) if defaults['metadata_uploaded_preserve']: defaults['metadata_xml'] = xml_file if identifier: if ResourceBase.objects.filter(uuid=identifier).count(): logger.error( "The UUID identifier from the XML Metadata is already in use in this system." ) raise GeoNodeException( _("The UUID identifier from the XML Metadata is already in use in this system." )) else: defaults['uuid'] = identifier for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value, defaults={ 'description': '', 'gn_description': value }) key = 'category' defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) if keywords and regions_unresolved: keywords.extend(convert_keyword(regions_unresolved)) # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. created = False layer = None try: with transaction.atomic(): if overwrite: try: layer = Layer.objects.get(name=valid_name) except Layer.DoesNotExist: layer = None if not layer: if not metadata_upload_form: layer = Layer.objects.filter( name=valid_name, workspace=settings.DEFAULT_WORKSPACE).first() if not layer: layer = Layer.objects.create( name=valid_name, workspace=settings.DEFAULT_WORKSPACE) created = True elif identifier: layer = Layer.objects.filter(uuid=identifier).first() if not layer: layer = Layer.objects.create(uuid=identifier) created = True except IntegrityError: raise # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: # update with new information defaults['title'] = defaults.get('title', None) or layer.title defaults['abstract'] = defaults.get('abstract', None) or layer.abstract defaults['bbox_polygon'] = defaults.get('bbox_polygon', None) or layer.bbox_polygon defaults['ll_bbox_polygon'] = defaults.get( 'll_bbox_polygon', None) or layer.ll_bbox_polygon defaults['is_approved'] = defaults.get( 'is_approved', is_approved) or layer.is_approved defaults['is_published'] = defaults.get( 'is_published', is_published) or layer.is_published defaults['license'] = defaults.get('license', None) or layer.license defaults['category'] = defaults.get('category', None) or layer.category if upload_session: if layer.upload_session: layer.upload_session.date = upload_session.date layer.upload_session.user = upload_session.user layer.upload_session.error = upload_session.error layer.upload_session.traceback = upload_session.traceback layer.upload_session.context = upload_session.context upload_session = layer.upload_session else: layer.upload_session = upload_session if upload_session: defaults['upload_session'] = upload_session upload_session.resource = layer upload_session.processed = False upload_session.save() layer = KeywordHandler(layer, keywords).set_keywords() # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: if not layer.regions: layer.regions = regions_resolved else: layer.regions.clear() layer.regions.add(*regions_resolved) # Assign and save the charset using the Layer class' object (layer) if charset != 'UTF-8': layer.charset = charset if not defaults.get('title', title): defaults['title'] = layer.title or layer.name if not defaults.get('abstract', abstract): defaults['abstract'] = layer.abstract or '' to_update = {} to_update['upload_session'] = defaults.pop('upload_session', layer.upload_session) to_update['storeType'] = defaults.pop('storeType', layer.storeType) to_update['charset'] = defaults.pop('charset', layer.charset) to_update.update(defaults) if defaults.get('date', date) is not None: to_update['date'] = defaults.get( 'date', datetime.strptime(date, '%Y-%m-%d %H:%M:%S') if date else None) # Update ResourceBase if not to_update: pass else: try: with transaction.atomic(): if 'spatial_representation_type' in defaults: _spatial_ref_type = defaults.pop( 'spatial_representation_type') _spatial_ref_type.save() defaults['spatial_representation_type'] = _spatial_ref_type ResourceBase.objects.filter( id=layer.resourcebase_ptr.id).update(**defaults) Layer.objects.filter(id=layer.id).update(**to_update) # Refresh from DB layer.refresh_from_db() # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite # Blank out the store if overwrite is true. # geoserver_post_save_signal should upload the new file if needed layer.store = '' if overwrite else layer.store except IntegrityError: raise try: with transaction.atomic(): layer.save(notify=True) except IntegrityError: raise return layer
def file_upload( filename, name=None, user=None, title=None, abstract=None, keywords=[], category=None, regions=[], skip=True, overwrite=False, charset="UTF-8", ): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace("_", " ") # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace("-", "_") if category is not None: categories = TopicCategory.objects.filter(Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, "rb") as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name="%s.%s" % (assigned_name or valid_name, type_name)) ) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { "upload_session": upload_session, "title": title, "abstract": abstract, "owner": user, "charset": charset, "bbox_x0": bbox_x0, "bbox_x1": bbox_x1, "bbox_y0": bbox_y0, "bbox_y1": bbox_y1, "is_published": is_published, "category": category, } # set metadata if "xml" in files: xml_file = open(files["xml"]) defaults["metadata_uploaded"] = True # get model properties from XML vals, regions, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == "spatial_representation_type": value = SpatialRepresentationType(identifier=value) elif key == "topic_category": value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={"description": "", "gn_description": value} ) key = "category" defaults[key] = value else: defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, "NLP_ENABLED", False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict( { "title": defaults.get("title", None), "abstract": defaults.get("abstract", None), "purpose": defaults.get("purpose", None), } ) if nlp_metadata: regions_resolved.extend(nlp_metadata.get("regions", [])) keywords.extend(nlp_metadata.get("keywords", [])) except: print "NLP extraction failed." # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults["storeType"] = "dataStore" # If it is a raster file, get the resolution. if is_raster(filename): defaults["storeType"] = "coverageStore" # Create a Django object. layer, created = Layer.objects.get_or_create(name=valid_name, defaults=defaults) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: layer.keywords.add(*keywords) # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: layer.regions.add(*regions_resolved) return layer
def file_upload(filename, name=None, user=None, title=None, abstract=None, keywords=[], category=None, regions=[], date=None, skip=True, overwrite=False, charset='UTF-8', metadata_uploaded_preserve=False): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') if category is not None: categories = TopicCategory.objects.filter(Q(identifier__iexact=category) | Q(gn_description__iexact=category)) if len(categories) == 1: category = categories[0] else: category = None # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create(name=type_name, file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_published': is_published, 'category': category } # set metadata if 'xml' in files: with open(files['xml']) as f: xml_file = f.read() defaults['metadata_uploaded'] = True defaults['metadata_uploaded_preserve'] = metadata_uploaded_preserve # get model properties from XML identifier, vals, regions, keywords = set_metadata(xml_file) if defaults['metadata_uploaded_preserve']: defaults['metadata_xml'] = xml_file defaults['uuid'] = identifier for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={'description': '', 'gn_description': value}) key = 'category' defaults[key] = value else: defaults[key] = value regions_resolved, regions_unresolved = resolve_regions(regions) keywords.extend(regions_unresolved) if getattr(settings, 'NLP_ENABLED', False): try: from geonode.contrib.nlp.utils import nlp_extract_metadata_dict nlp_metadata = nlp_extract_metadata_dict({ 'title': defaults.get('title', None), 'abstract': defaults.get('abstract', None), 'purpose': defaults.get('purpose', None)}) if nlp_metadata: regions_resolved.extend(nlp_metadata.get('regions', [])) keywords.extend(nlp_metadata.get('keywords', [])) except: print "NLP extraction failed." # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create( name=valid_name, defaults=defaults ) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) keywords = list(set(keywords)) if keywords: if len(keywords) > 0: layer.keywords.add(*keywords) # Assign the regions (needs to be done after saving) regions_resolved = list(set(regions_resolved)) if regions_resolved: if len(regions_resolved) > 0: layer.regions.add(*regions_resolved) if date is not None: layer.date = datetime.strptime(date, '%Y-%m-%d %H:%M:%S') layer.save() return layer
def file_upload(filename, name=None, user=None, title=None, abstract=None, skip=True, overwrite=False, keywords=[], charset='UTF-8'): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name='%s.%s' % (valid_name, type_name))) # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, } # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), gn_description=value) key = 'category' else: defaults[key] = value # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create(name=valid_name, defaults=defaults) # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session layer.save() # Assign the keywords (needs to be done after saving) if len(keywords) > 0: layer.keywords.add(*keywords) return layer
def handle(self, url, name, type, method, console=sys.stdout, **options): user = options.get('user') owner = get_valid_user(user) limit = options.get('limit') register_service = True # First Check if this service already exists based on the URL base_url = url try: service = Service.objects.get(base_url=base_url) except Service.DoesNotExist: service = None if service is not None: print("This is an existing Service") register_service = False # Then Check that the name is Unique try: service = Service.objects.get(name=name) except Service.DoesNotExist: service = None if service is not None: print("This is an existing service using this name.\n" "Please specify a different name.") if register_service: if method == 'I': form = ExchangeCreateServiceForm(data={ 'url': base_url, 'type': type }) if form.is_valid(): service_handler = form.cleaned_data["service_handler"] service = service_handler.create_geonode_service( owner=owner) service.full_clean() service.save() service.keywords.add(*service_handler.get_keywords()) service.set_default_permissions() service_handler = get_service_handler( service.base_url, service.type) available_resources = service_handler.get_resources() print("Service created with id of %d" % service.id) print(" Harvesting...") processed = 0 for resource in available_resources: if processed < limit: try: service_handler.harvest_resource( resource.id, service) processed = processed + 1 except: print(" - Failed Harvesting Resource Id: {}". format(resource.id)) else: break else: print(form.errors) else: print("Indexing is only available.") print('Done')
def test_layer_permissions(self): try: # Test permissions on a layer # grab bobby bobby = get_user_model().objects.get(username="******") layers = Layer.objects.all()[:2].values_list('id', flat=True) test_perm_layer = Layer.objects.get(id=layers[0]) thefile = os.path.join( gisdata.VECTOR_DATA, 'san_andres_y_providencia_poi.shp') layer = geoserver_upload( test_perm_layer, thefile, bobby, 'san_andres_y_providencia_poi', overwrite=True ) self.assertIsNotNone(layer) # Reset GeoFence Rules purge_geofence_all() geofence_rules_count = get_geofence_rules_count() self.assertTrue(geofence_rules_count == 0) ignore_errors = False skip_unadvertised = False skip_geonode_registered = False remove_deleted = True verbosity = 2 owner = get_valid_user('admin') workspace = 'geonode' filter = None store = None permissions = {'users': {"admin": ['change_layer_data']}} gs_slurp( ignore_errors, verbosity=verbosity, owner=owner, console=StreamToLogger(logger, logging.INFO), workspace=workspace, store=store, filter=filter, skip_unadvertised=skip_unadvertised, skip_geonode_registered=skip_geonode_registered, remove_deleted=remove_deleted, permissions=permissions, execute_signals=True) layer = Layer.objects.get(title='san_andres_y_providencia_poi') check_layer(layer) geofence_rules_count = get_geofence_rules_count() _log("0. geofence_rules_count: %s " % geofence_rules_count) self.assertEquals(geofence_rules_count, 2) # Set the layer private for not authenticated users layer.set_permissions({'users': {'AnonymousUser': []}}) url = 'http://localhost:8080/geoserver/geonode/ows?' \ 'LAYERS=geonode%3Asan_andres_y_providencia_poi&STYLES=' \ '&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap' \ '&SRS=EPSG%3A4326' \ '&BBOX=-81.394599749999,13.316009005566,' \ '-81.370560451855,13.372728455566' \ '&WIDTH=217&HEIGHT=512' # test view_resourcebase permission on anonymous user request = urllib2.Request(url) response = urllib2.urlopen(request) self.assertTrue( response.info().getheader('Content-Type'), 'application/vnd.ogc.se_xml;charset=UTF-8' ) # test WMS with authenticated user that has not view_resourcebase: # the layer must be not accessible (response is xml) request = urllib2.Request(url) base64string = base64.encodestring( '%s:%s' % ('bobby', 'bob')).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string) response = urllib2.urlopen(request) self.assertTrue( response.info().getheader('Content-Type'), 'application/vnd.ogc.se_xml;charset=UTF-8' ) # test WMS with authenticated user that has view_resourcebase: the layer # must be accessible (response is image) assign_perm('view_resourcebase', bobby, layer.get_self_resource()) request = urllib2.Request(url) base64string = base64.encodestring( '%s:%s' % ('bobby', 'bob')).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string) response = urllib2.urlopen(request) self.assertTrue(response.info().getheader('Content-Type'), 'image/png') # test change_layer_data # would be nice to make a WFS/T request and test results, but this # would work only on PostGIS layers # test change_layer_style url = 'http://localhost:8000/gs/rest/workspaces/geonode/styles/san_andres_y_providencia_poi.xml' sld = """<?xml version="1.0" encoding="UTF-8"?> <sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"> <sld:NamedLayer> <sld:Name>geonode:san_andres_y_providencia_poi</sld:Name> <sld:UserStyle> <sld:Name>san_andres_y_providencia_poi</sld:Name> <sld:Title>san_andres_y_providencia_poi</sld:Title> <sld:IsDefault>1</sld:IsDefault> <sld:FeatureTypeStyle> <sld:Rule> <sld:PointSymbolizer> <sld:Graphic> <sld:Mark> <sld:Fill> <sld:CssParameter name="fill">#8A7700 </sld:CssParameter> </sld:Fill> <sld:Stroke> <sld:CssParameter name="stroke">#bbffff </sld:CssParameter> </sld:Stroke> </sld:Mark> <sld:Size>10</sld:Size> </sld:Graphic> </sld:PointSymbolizer> </sld:Rule> </sld:FeatureTypeStyle> </sld:UserStyle> </sld:NamedLayer> </sld:StyledLayerDescriptor>""" # user without change_layer_style cannot edit it self.assertTrue(self.client.login(username='******', password='******')) response = self.client.put(url, sld, content_type='application/vnd.ogc.sld+xml') self.assertEquals(response.status_code, 401) # user with change_layer_style can edit it assign_perm('change_layer_style', bobby, layer) perm_spec = { 'users': { 'bobby': ['view_resourcebase', 'change_resourcebase', ] } } layer.set_permissions(perm_spec) response = self.client.get(url) self.assertEquals(response.status_code, 200) response = self.client.put(url, sld, content_type='application/vnd.ogc.sld+xml') finally: try: layer.delete() except BaseException: pass
def layer_metadata(request, layername, template='layers/layer_metadata.html'): user = get_valid_user() ogc_server_settings.DATASTORE = request.user.profile.user.username layer = _resolve_layer(request, layername, 'layers.change_layer', _PERMISSION_MSG_METADATA) layer_attribute_set = inlineformset_factory(Layer, Attribute, extra=0, form=LayerAttributeForm, ) poc = layer.poc metadata_author = layer.metadata_author ContactRole.objects.get(resource=layer, role=layer.poc_role) ContactRole.objects.get(resource=layer, role=layer.metadata_author_role) if request.method == "POST": layer_form = LayerForm(request.POST, instance=layer, prefix="layer") attribute_form = layer_attribute_set(request.POST, instance=layer, prefix="layer_attribute_set", queryset=Attribute.objects.order_by('display_order')) else: layer_form = LayerForm(instance=layer, prefix="layer") attribute_form = layer_attribute_set(instance=layer, prefix="layer_attribute_set", queryset=Attribute.objects.order_by('display_order')) if request.method == "POST" and layer_form.is_valid() and attribute_form.is_valid(): new_poc = layer_form.cleaned_data['poc'] new_author = layer_form.cleaned_data['metadata_author'] new_keywords = layer_form.cleaned_data['keywords'] if new_poc is None: if poc.user is None: poc_form = ProfileForm(request.POST, prefix="poc", instance=poc) else: poc_form = ProfileForm(request.POST, prefix="poc") if poc_form.has_changed and poc_form.is_valid(): new_poc = poc_form.save() if new_author is None: if metadata_author.user is None: author_form = ProfileForm(request.POST, prefix="author", instance=metadata_author) else: author_form = ProfileForm(request.POST, prefix="author") if author_form.has_changed and author_form.is_valid(): new_author = author_form.save() for form in attribute_form.cleaned_data: la = Attribute.objects.get(id=int(form['id'].id)) la.description = form["description"] la.attribute_label = form["attribute_label"] la.visible = form["visible"] la.display_order = form["display_order"] la.save() if new_poc is not None and new_author is not None: the_layer = layer_form.save() the_layer.poc = new_poc the_layer.metadata_author = new_author the_layer.keywords.clear() the_layer.keywords.add(*new_keywords) return HttpResponseRedirect(reverse('layer_detail', args=(layer.typename,))) if poc.user is None: poc_form = ProfileForm(instance=poc, prefix="poc") else: layer_form.fields['poc'].initial = poc.id poc_form = ProfileForm(prefix="poc") poc_form.hidden=True if metadata_author.user is None: author_form = ProfileForm(instance=metadata_author, prefix="author") else: layer_form.fields['metadata_author'].initial = metadata_author.id author_form = ProfileForm(prefix="author") author_form.hidden=True return render_to_response(template, RequestContext(request, { "layer": layer, "layer_form": layer_form, "poc_form": poc_form, "author_form": author_form, "attribute_form": attribute_form, }))