Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
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
    }))
Пример #4
0
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
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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
Пример #8
0
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:
Пример #9
0
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})
Пример #10
0
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)
Пример #11
0
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
Пример #12
0
    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']
Пример #13
0
    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']
Пример #14
0
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)
Пример #15
0
 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)
Пример #16
0
 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)
Пример #17
0
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)
Пример #18
0
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]
Пример #19
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')
Пример #20
0
    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))
Пример #21
0
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)
Пример #22
0
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})
Пример #23
0
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)
Пример #24
0
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 }))
Пример #25
0
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")
Пример #26
0
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:
Пример #27
0
    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))
Пример #28
0
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")
Пример #29
0
    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))
Пример #30
0
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
Пример #31
0
    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
Пример #32
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')
        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']))
Пример #33
0
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
Пример #34
0
    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
Пример #35
0
    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)))
Пример #36
0
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
Пример #37
0
    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')
Пример #38
0
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
Пример #39
0
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
                    }
                )
            )
Пример #40
0
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
Пример #41
0
    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))
Пример #42
0
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
Пример #43
0
    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)
Пример #44
0
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
Пример #45
0
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
Пример #46
0
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
Пример #47
0
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
Пример #48
0
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
Пример #49
0
    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')
Пример #50
0
    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
Пример #51
0
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,
    }))