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)
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}
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}
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 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}
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}
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'))
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()
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))
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)
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))
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)
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)
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))
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))
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))
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)
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}
def roles_update(request, instance): role_perms = json_from_request(request) _update_perms_from_object(role_perms, instance) return HttpResponse(_('Updated roles'))
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
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)
def update_instance_fields(request, instance, validation_fn=None): json_data = json_from_request(request) return _update_instance_fields(json_data, instance, validation_fn)