Example #1
0
def update_instance_fields(request, instance, validation_fn=None):
    json_data = json_from_request(request)
    # The update is a PUT request but the query string param appears in the GET
    # dict
    should_update_universal_rev = 'update_universal_rev' in request.GET
    return _update_instance_fields(json_data, instance, validation_fn,
                                   should_update_universal_rev)
Example #2
0
def set_fields(request, instance):
    data = json_from_request(request)
    instance.web_detail_fields = data['web_detail_fields']
    instance.mobile_api_fields = data['mobile_api_fields']
    instance.save()

    return {'success': True}
Example #3
0
def update_benefits(request, instance):
    conv = instance.eco_benefits_conversion or _get_default_conversions()

    valid_fields = ('currency_symbol', 'electricity_kwh_to_currency',
                    'natural_gas_kbtu_to_currency', 'h20_gal_to_currency',
                    'co2_lb_to_currency', 'o3_lb_to_currency',
                    'nox_lb_to_currency', 'pm10_lb_to_currency',
                    'sox_lb_to_currency', 'voc_lb_to_currency')

    valid_fields = [
        "benefitCurrencyConversion." + field for field in valid_fields
    ]

    updated_values = json_from_request(request)

    for field, value in updated_values.iteritems():
        if field in valid_fields:
            field_part = dotted_split(field, 2)[1]
            setattr(conv, field_part, value)
        else:
            raise Exception(
                'invalid field specified %s for benefit conversion' % field)

    try:
        conv.save()
    except ValidationError as e:
        raise ValidationError(
            package_field_errors('benefitCurrencyConversion', e))

    instance.eco_benefits_conversion = conv
    instance.update_eco_rev()
    instance.save()

    return {'ok': True}
Example #4
0
def update_user_roles(request, instance):
    role_updates = json_from_request(request)

    admin_user = request.user

    for Model, key in ((InstanceUser, 'users'),
                       (InstanceInvitation, 'invites')):
        updates = role_updates.get(key, {})

        for pk, updated_info in updates.iteritems():
            model = Model.objects.get(pk=pk)

            updated_role = int(updated_info.get('role', model.role_id))
            is_admin = updated_info.get('admin', model.admin)

            if model.role_id != updated_role or is_admin != model.admin:
                model.role_id = updated_role
                model.admin = is_admin

                if Model == InstanceInvitation:
                    model.save()
                elif (does_user_own_instance(instance, model.user)
                      and not is_admin):
                    raise ValidationError('Instance owner must be admin')
                else:
                    model.save_with_user(admin_user)

    return HttpResponse(_('Updated role assignments'))
Example #5
0
def set_fields(request, instance):
    data = json_from_request(request)
    instance.web_detail_fields = data['web_detail_fields']
    instance.mobile_api_fields = data['mobile_api_fields']
    instance.save()

    return {'success': True}
Example #6
0
def update_instance_fields(request, instance, validation_fn=None):
    json_data = json_from_request(request)
    # The update is a PUT request but the query string param appears in the GET
    # dict
    should_update_universal_rev = 'update_universal_rev' in request.GET
    return _update_instance_fields(json_data, instance, validation_fn,
                                   should_update_universal_rev)
Example #7
0
def create_plot_optional_tree(request, instance):
    response = HttpResponse()

    # Unit tests fail to access request.body
    request_dict = json_from_request(request)

    # The Django form used to validate and save plot and tree
    # information expects a flat dictionary. Allowing the tree
    # and geometry details to be in nested dictionaries in API
    # calls clarifies, to API clients, the distinction between
    # Plot and Tree and groups the coordinates along with their
    # spatial reference
    flatten_plot_dict_with_tree_and_geometry(request_dict)

    # The new plot/tree form requires specific field names that
    # do not directly match up with the model objects (e.g. the
    # form expects a 'species_id' field) so this helper function
    # renames keys in the dictionary to match what the form expects
    rename_plot_request_dict_fields(request_dict)

    plot = create_plot(request.user, instance, **request_dict)

    if type(plot) is list:
        response.status_code = 400
        response.content = json.dumps({'error': plot})
    else:
        response.status_code = 201
        new_plot = plot_to_dict(plot, longform=True, user=request.user)
        response.content = json.dumps(new_plot)

    return response
def green_infrastructure(request, instance):
    json_data = json_from_request(request)
    new_data = {}
    increment_universal_rev = False
    for identifier, value in json_data.iteritems():
        model, field_name = dotted_split(identifier, 2, maxsplit=1)
        if field_name.startswith('config.map_feature_types') or \
           field_name.startswith('config.map_feature_config'):
            if not instance.feature_enabled('green_infrastructure'):
                raise PermissionDenied("The Green Infrastructure module is "
                                       "not enabled for this tree map")
            increment_universal_rev = True
        if field_name.startswith('config.map_feature_types'):
            __, __, mft_name = dotted_split(field_name, 3, maxsplit=2)
            if value:
                instance.add_map_feature_types([mft_name])
            else:
                instance.remove_map_feature_types([mft_name])
        else:
            new_data[identifier] = value

    error_dict = {}
    _validate_and_set_individual_values(new_data, instance, error_dict)
    _cross_validate_values(new_data, instance, error_dict)
    if error_dict:
        raise ValidationError(
            package_field_errors('instance', ValidationError(error_dict)))
    if increment_universal_rev:
        instance.update_universal_rev()
    instance.save()
    return {'ok': True}
Example #9
0
def update_user_roles(request, instance):
    role_updates = json_from_request(request)

    admin_user = request.user

    for Model, key in ((InstanceUser, 'users'),
                       (InstanceInvitation, 'invites')):
        updates = role_updates.get(key, {})

        for pk, updated_info in updates.iteritems():
            model = Model.objects.get(pk=pk)

            updated_role = int(updated_info.get('role', model.role_id))
            is_admin = updated_info.get('admin', model.admin)

            if model.role_id != updated_role or is_admin != model.admin:
                model.role_id = updated_role
                model.admin = is_admin

                if Model == InstanceInvitation:
                    model.save()
                elif (does_user_own_instance(instance, model.user)
                      and not is_admin):
                    raise ValidationError('Instance owner must be admin')
                else:
                    model.save_with_user(admin_user)

    return HttpResponse(_('Updated role assignments'))
def green_infrastructure(request, instance):
    json_data = json_from_request(request)
    new_data = {}
    increment_universal_rev = False
    for identifier, value in json_data.iteritems():
        model, field_name = dotted_split(identifier, 2, maxsplit=1)
        if field_name.startswith('config.map_feature_types') or \
           field_name.startswith('config.map_feature_config'):
            if not instance.feature_enabled('green_infrastructure'):
                raise PermissionDenied("The Green Infrastructure module is "
                                       "not enabled for this tree map")
            increment_universal_rev = True
        if field_name.startswith('config.map_feature_types'):
            __, __, mft_name = dotted_split(field_name, 3, maxsplit=2)
            if value:
                instance.add_map_feature_types([mft_name])
            else:
                instance.remove_map_feature_types([mft_name])
        else:
            new_data[identifier] = value

    error_dict = {}
    _validate_and_set_individual_values(new_data, instance, error_dict)
    _cross_validate_values(new_data, instance, error_dict)
    if error_dict:
        raise ValidationError(package_field_errors('instance',
                              ValidationError(error_dict)))
    if increment_universal_rev:
        instance.update_universal_rev()
    instance.save()
    return {'ok': True}
Example #11
0
def udf_update_choice(request, instance, udf_id):
    params = json_from_request(request)

    udf = get_object_or_404(UserDefinedFieldDefinition, pk=udf_id)

    _udf_update_choice(udf, instance, params)

    return HttpResponse(_('Updated Custom Field'))
Example #12
0
def udf_update_choice(request, instance, udf_id):
    params = json_from_request(request)

    udf = get_object_or_404(UserDefinedFieldDefinition, pk=udf_id)

    _udf_update_choice(udf, instance, params)

    return HttpResponse(_('Updated Custom Field'))
Example #13
0
def set_search_config(request, instance):
    search_fields = json_from_request(request)
    for prop in ('search_config', 'mobile_search_fields'):
        config = deepcopy(getattr(instance, prop))
        for key, val in search_fields[prop].iteritems():
            config[key] = search_fields[prop][key]

        setattr(instance, prop, config)
    instance.save()
Example #14
0
def set_search_config(request, instance):
    search_fields = json_from_request(request)
    for prop in ('search_config', 'mobile_search_fields'):
        config = deepcopy(getattr(instance, prop))
        for key, val in search_fields[prop].iteritems():
            config[key] = search_fields[prop][key]

        setattr(instance, prop, config)
    instance.save()
Example #15
0
def update_user(request, user):
    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = key.split(".", 1)
            if model != "user":
                return bad_request_json_response('All fields should be prefixed with "user."')
            if field not in USER_PROFILE_FIELDS:
                return bad_request_json_response(field + " is not an updatable field")
        except ValueError:
            return bad_request_json_response('All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError, ve:
        return bad_request_json_response(validation_error_dict=package_validation_errors("user", ve))
Example #16
0
def update_external_link(request, instance):
    def validator(field_name, value, model_name):
        if model_name != 'instance':
            return [_('Invalid model name, must be a field on instance')]

        if field_name not in {
                'config.externalLink.text', 'config.externalLink.url'
        }:
            return [_('Invalid field name')]
        elif field_name == 'config.externalLink.url':
            try:
                if value and len(value) > 0:
                    URLValidator()(value)
            except ValidationError:
                return [_('You must specify a valid url')]

            if not validate_token_template(value):
                return [
                    _('Invalid token, the allowed values are'
                      ': %(list_of_url_tokens)s') % {
                          'list_of_url_tokens': get_url_tokens_for_display()
                      }
                ]

        return None

    data = json_from_request(request)
    url = data.get('instance.config.externalLink.url',
                   instance.config.get('externalLink.url'))
    text = data.get('instance.config.externalLink.text',
                    instance.config.get('externalLink.text'))
    if bool(url) ^ bool(text):
        if text:
            field, other_field = 'url', _('Link Text')
        else:
            field, other_field = 'text', _('Link URL')

        raise ValidationError({
            'instance.config.externalLink.%s' % field: [
                _("This field is required when %(other_field)s is present") % {
                    'other_field': other_field
                }
            ]
        })

    return update_instance_fields(request, instance, validator)
Example #17
0
def update_user(request, user):
    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = dotted_split(key, 2, cls=ValueError)
            if model != 'user':
                raise ValidationError(
                    'All fields should be prefixed with "user."')
            if field not in USER_PROFILE_FIELDS:
                raise ValidationError(field + ' is not an updatable field')
        except ValueError:
            raise ValidationError('All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError as ve:
        raise ValidationError(package_field_errors('user', ve))
Example #18
0
def update_user(request, user):
    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = dotted_split(key, 2, cls=ValueError)
            if model != 'user':
                raise ValidationError(
                    'All fields should be prefixed with "user."')
            if field not in USER_PROFILE_FIELDS:
                raise ValidationError(field + ' is not an updatable field')
        except ValueError:
            raise ValidationError('All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError as ve:
        raise ValidationError(package_field_errors('user', ve))
Example #19
0
def create_user_role(request, instance):
    data = json_from_request(request)

    email = data.get('email')

    if not email:
        raise ValidationError(_("User's email is required"))

    error = can_add_user(instance)
    if isinstance(error, ValidationError):
        raise error

    try:
        user = User.objects.get(email=email)
        add_user_to_instance(request, user, instance, request.user)
    except ObjectDoesNotExist:
        invite_user_with_email_to_instance(request, email, instance)

    return user_roles_list(request, instance)
Example #20
0
def create_user_role(request, instance):
    data = json_from_request(request)

    email = data.get('email')

    if not email:
        raise ValidationError(_("User's email is required"))

    error = can_add_user(instance)
    if isinstance(error, ValidationError):
        raise error

    try:
        user = User.objects.get(email=email)
        add_user_to_instance(request, user, instance, request.user)
    except ObjectDoesNotExist:
        invite_user_with_email_to_instance(request, email, instance)

    return user_roles_list(request, instance)
Example #21
0
def roles_create(request, instance):
    params = json_from_request(request)

    role_name = params.get('name', None)

    if not role_name:
        return HttpResponseBadRequest(
            _("Must provide a name for the new role."))

    role, created = Role.objects.get_or_create(name=role_name,
                                               instance=instance,
                                               rep_thresh=0)

    if created is False:
        return HttpResponseBadRequest(
            _("A role with name '%(role_name)s' already exists") %
            {'role_name': role_name})

    add_default_permissions(instance, roles=[role])

    return roles_list(request, instance)
Example #22
0
def update_user(request, user):
    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = key.split('.', 1)
            if model != 'user':
                return bad_request_json_response(
                    'All fields should be prefixed with "user."')
            if field not in ['first_name', 'last_name', 'email']:
                return bad_request_json_response(
                    field + ' is not an updatable field')
        except ValueError:
            return bad_request_json_response(
                'All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError, ve:
        return bad_request_json_response(
            validation_error_dict=package_validation_errors('user', ve))
Example #23
0
def roles_create(request, instance):
    params = json_from_request(request)

    role_name = params.get('name', None)

    if not role_name:
        return HttpResponseBadRequest(
            _("Must provide a name for the new role."))

    role, created = Role.objects.get_or_create(name=role_name,
                                               instance=instance,
                                               rep_thresh=0)

    if created is False:
        return HttpResponseBadRequest(
            _("A role with name '%(role_name)s' already exists") %
            {'role_name': role_name})

    add_default_permissions(instance, roles=[role])

    return roles_list(request, instance)
Example #24
0
def update_user(request, username):
    user = get_object_or_404(User, username=username)
    if user != request.user:
        return HttpResponseForbidden()

    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = key.split(".", 1)
            if model != "user":
                return bad_request_json_response('All fields should be prefixed with "user."')
            if field not in ["first_name", "last_name", "email"]:
                return bad_request_json_response(field + " is not an updatable field")
        except ValueError:
            return bad_request_json_response('All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError, ve:
        return bad_request_json_response(validation_error_dict=package_validation_errors("user", ve))
Example #25
0
def update_user(request, user):
    new_values = json_from_request(request) or {}
    for key in new_values:
        try:
            model, field = key.split('.', 1)
            if model != 'user':
                return bad_request_json_response(
                    'All fields should be prefixed with "user."')
            if field not in USER_EDIT_FIELDS:
                return bad_request_json_response(field +
                                                 ' is not an updatable field')
        except ValueError:
            return bad_request_json_response(
                'All fields should be prefixed with "user."')
        setattr(user, field, new_values[key])
    try:
        user.save()
        return {"ok": True}
    except ValidationError, ve:
        return bad_request_json_response(
            validation_error_dict=package_validation_errors('user', ve))
Example #26
0
def update_external_link(request, instance):

    def validator(field_name, value, model_name):
        if model_name != 'instance':
            return [_('Invalid model name, must be a field on instance')]

        if field_name not in {'config.externalLink.text',
                              'config.externalLink.url'}:
            return [_('Invalid field name')]
        elif field_name == 'config.externalLink.url':
            try:
                if value and len(value) > 0:
                    URLValidator()(value)
            except ValidationError:
                return [_('You must specify a valid url')]

            if not validate_token_template(value):
                return [_('Invalid token, the allowed values are'
                          ': %(list_of_url_tokens)s') %
                        {'list_of_url_tokens': get_url_tokens_for_display()}]

        return None

    data = json_from_request(request)
    url = data.get('instance.config.externalLink.url',
                   instance.config.get('externalLink.url'))
    text = data.get('instance.config.externalLink.text',
                    instance.config.get('externalLink.text'))
    if bool(url) ^ bool(text):
        if text:
            field, other_field = 'url', _('Link Text')
        else:
            field, other_field = 'text', _('Link URL')

        raise ValidationError(
            {'instance.config.externalLink.%s' % field:
             [_("This field is required when %(other_field)s is present") %
              {'other_field': other_field}]})

    return update_instance_fields(request, instance, validator)
Example #27
0
def update_benefits(request, instance):
    conv = instance.eco_benefits_conversion or _get_default_conversions()

    valid_fields = ('currency_symbol',
                    'electricity_kwh_to_currency',
                    'natural_gas_kbtu_to_currency',
                    'h20_gal_to_currency',
                    'co2_lb_to_currency',
                    'o3_lb_to_currency',
                    'nox_lb_to_currency',
                    'pm10_lb_to_currency',
                    'sox_lb_to_currency',
                    'voc_lb_to_currency')

    valid_fields = ["benefitCurrencyConversion." + field
                    for field in valid_fields]

    updated_values = json_from_request(request)

    for field, value in updated_values.iteritems():
        if field in valid_fields:
            field_part = dotted_split(field, 2)[1]
            setattr(conv, field_part, value)
        else:
            raise Exception(
                'invalid field specified %s for benefit conversion' % field)

    try:
        conv.save()
    except ValidationError as e:
        raise ValidationError(
            package_field_errors('benefitCurrencyConversion', e))

    instance.eco_benefits_conversion = conv
    instance.update_eco_rev()
    instance.save()

    return {'ok': True}
Example #28
0
def roles_update(request, instance):
    role_perms = json_from_request(request)
    _update_perms_from_object(role_perms, instance)
    return HttpResponse(_('Updated roles'))
Example #29
0
def update_plot_and_tree(request, instance, plot_id):

    def set_attr_with_choice_correction(request, model, attr, value):
        if _attribute_requires_conversion(request, attr):
            conversions = settings.CHOICE_CONVERSIONS[attr]['forward']
            for (old, new) in conversions:
                if str(value) == str(old):
                    value = new
                    break
        setattr(model, attr, value)

    def get_attr_with_choice_correction(request, model, attr):
        value = getattr(model, attr)
        if _attribute_requires_conversion(request, attr):
            conversions = settings.CHOICE_CONVERSIONS[attr]['reverse']
            for (new, old) in conversions:
                if str(value) == str(new):
                    value = old
                    break
        return value

    response = HttpResponse()
    try:
        plot = Plot.objects.get(pk=plot_id)
    except Plot.DoesNotExist:
        response.status_code = 400
        response.content = json.dumps({
            "error": "No plot with id %s" % plot_id})
        return response

    request_dict = json_from_request(request)

    flatten_plot_dict_with_tree_and_geometry(request_dict)

    plot_field_whitelist = ['plot_width', 'plot_length', 'type',
                            'geocoded_address', 'edit_address_street',
                            'address_city', 'address_street', 'address_zip',
                            'power_lines', 'sidewalk_damage']

    # The Django form that creates new plots expects a 'plot_width'
    # parameter but the Plot model has a 'width' parameter so this
    # dict acts as a translator between request keys and model field names
    plot_field_property_name_dict = {
        'plot_width': 'width',
        'plot_length': 'length',
        'power_lines': 'powerline_conflict_potential'}

    plot_was_edited = False
    for plot_field_name in request_dict.keys():
        if plot_field_name in plot_field_whitelist:
            if plot_field_name in plot_field_property_name_dict:
                new_name = plot_field_property_name_dict[plot_field_name]
            else:
                new_name = plot_field_name
            new_value = request_dict[plot_field_name]
            if not compare_fields(get_attr_with_choice_correction(
                    request, plot, new_name), new_value):
                set_attr_with_choice_correction(
                    request, plot, new_name, new_value)
                plot_was_edited = True

    # TODO: Standardize on lon or lng
    if 'lat' in request_dict or 'lon' in request_dict or 'lng' in request_dict:
        new_geometry = Point(x=plot.geom.x, y=plot.geom.y)
        if 'lat' in request_dict:
            new_geometry.y = request_dict['lat']
        if 'lng' in request_dict:
            new_geometry.x = request_dict['lng']
        if 'lon' in request_dict:
            new_geometry.x = request_dict['lon']

        if plot.geom.x != new_geometry.x or plot.geom.y != new_geometry.y:
            plot.geom = new_geometry
            plot_was_edited = True

    if plot_was_edited:
        plot.save_with_user(request.user)

    tree_was_edited = False
    tree_was_added = False
    tree = plot.current_tree()
    tree_field_whitelist = ['species', 'diameter', 'height', 'canopy_height',
                            'canopy_condition', 'condition', 'pests']

    for tree_field in Tree._meta.fields:
        if ((tree_field.name in request_dict and
             tree_field.name in tree_field_whitelist)):
            if tree is None:
                tree = Tree(plot=plot, instance=instance)

                tree.plot = plot
                tree.last_updated_by = request.user
                tree.save_with_user(request.user)
                tree_was_added = True
            if tree_field.name == 'species':
                try:
                    if (((tree.species and
                          tree.species.pk != request_dict[tree_field.name])
                         or
                         (not tree.species
                          and request_dict[tree_field.name]))):
                        tree.species = Species.objects.get(
                            pk=request_dict[tree_field.name])
                        tree_was_edited = True
                except Exception:
                    response.status_code = 400
                    response.content = json.dumps(
                        {"error": "No species with id %s" %
                         request_dict[tree_field.name]})
                    return response
            else:  # tree_field.name != 'species'
                if not compare_fields(
                        get_attr_with_choice_correction(
                            request, tree, tree_field.name),
                        request_dict[tree_field.name]):
                    set_attr_with_choice_correction(
                        request, tree, tree_field.name,
                        request_dict[tree_field.name])

                    tree_was_edited = True

    if tree_was_added or tree_was_edited:
        tree.save_with_user(request.user)

    full_plot = Plot.objects.get(pk=plot.id)
    return_dict = plot_to_dict(full_plot, longform=True, user=request.user)
    response.status_code = 200
    response.content = json.dumps(return_dict)
    return response
Example #30
0
def roles_update(request, instance):
    role_perms = json_from_request(request)
    _update_perms_from_object(role_perms, instance)
    return HttpResponse(_('Updated roles'))
Example #31
0
def udf_create(request, instance):
    params = json_from_request(request)
    udf = lib.udf_create(params, instance)
    add_udf_notification(instance, to_model_name(udf.full_name))
    return udf_context(instance, udf)
Example #32
0
def udf_create(request, instance):
    params = json_from_request(request)
    udf = lib.udf_create(params, instance)
    add_udf_notification(instance, to_model_name(udf.full_name))
    return udf_context(instance, udf)
Example #33
0
def update_instance_fields(request, instance, validation_fn=None):
    json_data = json_from_request(request)
    return _update_instance_fields(json_data, instance, validation_fn)