def start_import(request, instance): import_type = request.REQUEST['type'] if import_type == TreeImportEvent.import_type: table = TABLE_ACTIVE_TREES factors = { 'plot_length_conversion_factor': 'unit_plot_length', 'plot_width_conversion_factor': 'unit_plot_width', 'diameter_conversion_factor': 'unit_diameter', 'tree_height_conversion_factor': 'unit_tree_height', 'canopy_height_conversion_factor': 'unit_canopy_height' } kwargs = { k: float(request.REQUEST.get(v, 1.0)) for (k, v) in factors.items() } else: table = TABLE_ACTIVE_SPECIES kwargs = { 'max_diameter_conversion_factor': storage_to_instance_units_factor(instance, 'tree', 'diameter'), 'max_tree_height_conversion_factor': storage_to_instance_units_factor(instance, 'tree', 'height') } process_csv(request, instance, import_type, **kwargs) return get_import_table(request, instance, table)
def start_import(request, instance): if not getattr(request, 'FILES'): return HttpResponseBadRequest("No attachment received") import_type = request.REQUEST['type'] if import_type == TreeImportEvent.import_type: table = TABLE_ACTIVE_TREES factors = { 'diameter_conversion_factor': ('tree', 'diameter'), 'tree_height_conversion_factor': ('tree', 'height'), 'canopy_height_conversion_factor': ('tree', 'canopy_height'), 'plot_length_conversion_factor': ('plot', 'length'), 'plot_width_conversion_factor': ('plot', 'width'), } else: table = TABLE_ACTIVE_SPECIES factors = { 'max_diameter_conversion_factor': ('tree', 'diameter'), 'max_tree_height_conversion_factor': ('tree', 'height'), } kwargs = {k: 1 / storage_to_instance_units_factor(instance, v[0], v[1]) for (k, v) in factors.items()} process_csv(request, instance, import_type, **kwargs) return get_import_table(request, instance, table)
def start_import(request, instance): if not getattr(request, 'FILES'): return HttpResponseBadRequest("No attachment received") import_type = request.REQUEST['type'] if import_type == TreeImportEvent.import_type: table = TABLE_ACTIVE_TREES factors = { 'diameter_conversion_factor': ('tree', 'diameter'), 'tree_height_conversion_factor': ('tree', 'height'), 'canopy_height_conversion_factor': ('tree', 'canopy_height'), 'plot_length_conversion_factor': ('plot', 'length'), 'plot_width_conversion_factor': ('plot', 'width'), } else: table = TABLE_ACTIVE_SPECIES factors = { 'max_diameter_conversion_factor': ('tree', 'diameter'), 'max_tree_height_conversion_factor': ('tree', 'height'), } kwargs = { k: 1 / storage_to_instance_units_factor(instance, v[0], v[1]) for (k, v) in factors.items() } process_csv(request, instance, import_type, **kwargs) return get_import_table(request, instance, table)
def convert_filter_units(instance, filter_dict): """ Convert the values in a filter dictionary from display units to database units. Mutates the `filter_dict` argument and returns it. """ for field_name, value in filter_dict.iteritems(): if field_name not in ['tree.diameter', 'tree.height', 'tree.canopy_height', 'plot.width', 'plot.length', 'bioswale.drainage_area', 'rainBarrel.capacity', 'rainGarden.drainage_area']: continue model_name, field = dotted_split(field_name, 2, maxsplit=1) if isinstance(value, dict): factor = 1 / storage_to_instance_units_factor(instance, model_name, field) for k in ['MIN', 'MAX', 'IS']: if k in value: try: if isinstance(value[k], dict): float_val = float(value[k]['VALUE']) value[k]['VALUE'] = factor * float_val else: float_val = float(value[k]) value[k] = factor * float_val except ValueError: # If the value is non-numeric we can just leave is as # is and let the filter logic handle it. pass return filter_dict
def _cm_to_instance_diameter_units(instance): # Get conversion factor from cm to instance's diameter units. # We know that OTM stores tree diameters in inches, so go from # cm to inches to instance units. in_to_instance = storage_to_instance_units_factor(instance, 'tree', 'diameter') cm_to_in = 1 / 2.54 cm_to_instance = cm_to_in * in_to_instance return cm_to_instance
def start_import(request, instance): import_type = request.REQUEST['type'] if import_type == TreeImportEvent.import_type: factors = {'plot_length_conversion_factor': 'unit_plot_length', 'plot_width_conversion_factor': 'unit_plot_width', 'diameter_conversion_factor': 'unit_diameter', 'tree_height_conversion_factor': 'unit_tree_height', 'canopy_height_conversion_factor': 'unit_canopy_height'} kwargs = {k: float(request.REQUEST.get(v, 1.0)) for (k, v) in factors.items()} else: kwargs = { 'max_diameter_conversion_factor': storage_to_instance_units_factor(instance, 'tree', 'diameter'), 'max_tree_height_conversion_factor': storage_to_instance_units_factor(instance, 'tree', 'height') } process_csv(request, instance, import_type, **kwargs) return list_imports(request, instance)
def validate_species_max(self, field, value_name, max_val, err): inputval = self.cleaned.get(field, None) if inputval and max_val: # inputval is in instance units but max_val is in storage units. # Convert max_val to instance units before comparing. factor = storage_to_instance_units_factor( self.import_event.instance, 'tree', value_name) max_val *= factor if inputval > max_val: self.append_error(err, field, max_val) return False return True
def add_perms(field_permissions, perms): for fp in field_permissions: model = fp.model_name.lower() field_key = '%s.%s' % (model, fp.field_name) if fp.allows_reads: if field_key in collection_udf_dict: choices = [] data_type = json.loads( collection_udf_dict[field_key].datatype) elif is_json_field_reference(fp.field_name): choices = None data_type = "string" else: model_inst = safe_get_model_class( fp.model_name)(instance=instance) data_type, __, __, choices = field_type_label_choices( model_inst, fp.field_name, fp.display_field_name) digits = get_digits_if_formattable(instance, model, fp.field_name) units = get_units_if_convertible(instance, model, fp.field_name) factor = 1.0 try: factor = storage_to_instance_units_factor( instance, model, fp.field_name) except KeyError: pass perms[field_key] = { 'data_type': data_type, 'choices': choices, 'units': units, 'digits': digits, 'canonical_units_factor': 1.0 / factor, 'can_write': fp.allows_writes, 'display_name': fp.display_field_name, 'field_name': fp.field_name, 'field_key': field_key, 'is_collection': field_key in collection_udf_dict }
def add_perms(field_permissions, perms): for fp in field_permissions: model = fp.model_name.lower() field_key = '%s.%s' % (model, fp.field_name) if fp.allows_reads: if field_key in collection_udf_dict: choices = [] data_type = json.loads( collection_udf_dict[field_key].datatype) elif is_json_field_reference(fp.field_name): choices = None data_type = "string" else: model_inst = safe_get_model_class(fp.model_name)( instance=instance) data_type, __, __, choices = field_type_label_choices( model_inst, fp.field_name, fp.display_field_name) digits = get_digits_if_formattable( instance, model, fp.field_name) units = get_units_if_convertible( instance, model, fp.field_name) factor = 1.0 try: factor = storage_to_instance_units_factor( instance, model, fp.field_name) except KeyError: pass perms[field_key] = { 'data_type': data_type, 'choices': choices, 'units': units, 'digits': digits, 'canonical_units_factor': 1.0 / factor, 'can_write': fp.allows_writes, 'display_name': fp.display_field_name, 'field_name': fp.field_name, 'field_key': field_key, 'is_collection': field_key in collection_udf_dict }
def _csv_field_serializer_map(instance, field_names): """ Create serializer functions that convert values to the proper units. """ map = {} convertable_fields = {'tree__diameter': ('tree', 'diameter'), 'tree__height': ('tree', 'height'), 'tree__canopy_height': ('tree', 'canopy_height'), 'width': ('plot', 'width'), 'length': ('plot', 'length')} def make_serializer(factor, digits): return lambda x: str(round(factor * x, digits)) for name, details in convertable_fields.iteritems(): model_name, field = details factor = storage_to_instance_units_factor(instance, model_name, field) _, digits = get_value_display_attr(instance, model_name, field, 'digits') digits = int(digits) map[name] = make_serializer(factor, digits) return map
def _csv_field_serializer_map(instance, field_names): """ Create serializer functions that convert values to the proper units. """ map = {} convertable_fields = { 'tree__diameter': ('tree', 'diameter'), 'tree__height': ('tree', 'height'), 'tree__canopy_height': ('tree', 'canopy_height'), 'width': ('plot', 'width'), 'length': ('plot', 'length') } def make_serializer(factor, digits): return lambda x: str(round(factor * x, digits)) for name, details in convertable_fields.iteritems(): model_name, field = details factor = storage_to_instance_units_factor(instance, model_name, field) _, digits = get_value_display_attr(instance, model_name, field, 'digits') digits = int(digits) map[name] = make_serializer(factor, digits) return map
def instance_info(request, instance): """ Get all the info we need about a given instance It also includes info about the fields available for the instance. If a user has been specified the field info will be tailored to that user """ user = request.user role = instance.default_role if user and not user.is_anonymous(): instance_user = user.get_instance_user(instance) if instance_user: role = instance_user.role collection_udfs = instance.collection_udfs collection_udf_dict = {"%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf for udf in collection_udfs} # collect perms for the given role/instance into a serializable # dictionary. If a field isn't at least readable, it doesn't # get sent over at all. perms = {} for fp in role_permissions(role, instance): model = fp.model_name.lower() field_key = '%s.%s' % (model, fp.field_name) if fp.allows_reads: if field_key in collection_udf_dict: choices = [] data_type = json.loads(collection_udf_dict[field_key].datatype) elif is_json_field_reference(fp.field_name): choices = None data_type = "string" else: model_inst = safe_get_model_class(fp.model_name)( instance=instance) data_type, __, choices = field_type_label_choices( model_inst, fp.field_name, fp.display_field_name) digits = get_digits_if_formattable( instance, model, fp.field_name) units = get_units_if_convertible( instance, model, fp.field_name) factor = 1.0 try: factor = storage_to_instance_units_factor( instance, model, fp.field_name) except KeyError: pass perms[field_key] = { 'data_type': data_type, 'choices': choices, 'units': units, 'digits': digits, 'canonical_units_factor': 1.0 / factor, 'can_write': fp.allows_writes, 'display_name': fp.display_field_name, 'field_name': fp.field_name, 'field_key': field_key, 'is_collection': field_key in collection_udf_dict } def get_key_for_group(field_group): for key in ('collection_udf_keys', 'field_keys'): if key in field_group: return key return None # Remove fields from mobile_api_fields if they are not present in perms # (Generally because the user doesn't have read permissions) # If no fields are left in a group, remove the group mobile_api_fields = copy.deepcopy(instance.mobile_api_fields) for field_group in mobile_api_fields: # Field group headers are stored in English, and translated when they # are sent out to the client field_group['header'] = _(field_group['header']) key = get_key_for_group(field_group) if key: field_group[key] = [field for field in field_group[key] if field in perms] readable_mobile_api_fields = [group for group in mobile_api_fields if group.get(get_key_for_group(group), None)] info = _instance_info_dict(instance) info['fields'] = perms info['field_key_groups'] = readable_mobile_api_fields info['search'] = mobile_search_fields(instance) info['date_format'] = _unicode_dateformat(instance.date_format) info['short_date_format'] = _unicode_dateformat(instance.short_date_format) info['meta_perms'] = { 'can_add_tree': perms_lib.plot_is_creatable(role), 'can_edit_tree': perms_lib.plot_is_writable(role), 'can_edit_tree_photo': perms_lib.treephoto_is_writable(role), } public_config_keys = ['scss_variables'] info['config'] = {x: instance.config[x] for x in instance.config if x in public_config_keys} if instance.logo: info['logoUrl'] = instance.logo.url return info
def instance_info(request, instance): """ Get all the info we need about a given instance It also includes info about the fields available for the instance. If a user has been specified the field info will be tailored to that user """ user = request.user role = instance.default_role if user and not user.is_anonymous(): instance_user = user.get_instance_user(instance) if instance_user: role = instance_user.role collection_udfs = instance.collection_udfs collection_udf_dict = { "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf for udf in collection_udfs } # collect perms for the given role/instance into a serializable # dictionary. If a field isn't at least readable, it doesn't # get sent over at all. perms = {} for fp in role_permissions(role, instance): model = fp.model_name.lower() field_key = '%s.%s' % (model, fp.field_name) if fp.allows_reads: if field_key in collection_udf_dict: choices = [] data_type = json.loads(collection_udf_dict[field_key].datatype) elif is_json_field_reference(fp.field_name): choices = None data_type = "string" else: model_inst = safe_get_model_class( fp.model_name)(instance=instance) data_type, __, choices = field_type_label_choices( model_inst, fp.field_name, fp.display_field_name) digits = get_digits_if_formattable(instance, model, fp.field_name) units = get_units_if_convertible(instance, model, fp.field_name) factor = 1.0 try: factor = storage_to_instance_units_factor( instance, model, fp.field_name) except KeyError: pass perms[field_key] = { 'data_type': data_type, 'choices': choices, 'units': units, 'digits': digits, 'canonical_units_factor': 1.0 / factor, 'can_write': fp.allows_writes, 'display_name': fp.display_field_name, 'field_name': fp.field_name, 'field_key': field_key, 'is_collection': field_key in collection_udf_dict } def get_key_for_group(field_group): for key in ('collection_udf_keys', 'field_keys'): if key in field_group: return key return None # Remove fields from mobile_api_fields if they are not present in perms # (Generally because the user doesn't have read permissions) # If no fields are left in a group, remove the group mobile_api_fields = copy.deepcopy(instance.mobile_api_fields) for field_group in mobile_api_fields: # Field group headers are stored in English, and translated when they # are sent out to the client field_group['header'] = _(field_group['header']) key = get_key_for_group(field_group) if key: field_group[key] = [ field for field in field_group[key] if field in perms ] readable_mobile_api_fields = [ group for group in mobile_api_fields if group.get(get_key_for_group(group), None) ] info = _instance_info_dict(instance) info['fields'] = perms info['field_key_groups'] = readable_mobile_api_fields info['search'] = mobile_search_fields(instance) info['date_format'] = _unicode_dateformat(instance.date_format) info['short_date_format'] = _unicode_dateformat(instance.short_date_format) info['meta_perms'] = { 'can_add_tree': perms_lib.plot_is_creatable(role), 'can_edit_tree': perms_lib.plot_is_writable(role), 'can_edit_tree_photo': perms_lib.treephoto_is_writable(role), } public_config_keys = ['scss_variables'] info['config'] = { x: instance.config[x] for x in instance.config if x in public_config_keys } if instance.logo: info['logoUrl'] = instance.logo.url return info