def extra_select_and_values_for_model(instance, job, table, model, prefix=None): if prefix: prefix += '__' else: prefix = '' perms = permissions(job.user, instance, model) extra_select = {} prefixed_names = [] dummy_instance = safe_get_model_class(model)() for perm in (perm for perm in perms if perm.permission_level >= FieldPermission.READ_ONLY): field_name = perm.field_name prefixed_name = prefix + field_name if field_name.startswith('udf:'): name = field_name[4:] extra_select[prefixed_name] = "%s.udfs->'%s'" % (table, name) else: if not model_hasattr(dummy_instance, field_name): # Exception will be raised downstream if you look for # a field on a model that no longer exists but still # has a stale permission record. Here we check for that # case and don't include the field if it does not exist. continue prefixed_names.append(prefixed_name) return (extra_select, prefixed_names)
def display_name(audit_or_model_or_name, instance=None): audit = None if isinstance(audit_or_model_or_name, (Audit, basestring)): if isinstance(audit_or_model_or_name, Audit): audit = audit_or_model_or_name name = audit.model extra_args = [audit.instance] else: name = audit_or_model_or_name extra_args = [] if name.startswith('udf:'): return UserDefinedCollectionValue.get_display_model_name( name, *extra_args) else: name = audit_or_model_or_name.__class__.__name__ if audit: return audit.model_display_name() cls = safe_get_model_class(name) if issubclass(cls, Convertible): # Sometimes instance will be None here, so we'll use the default name return cls.display_name(instance) else: return name
def extra_select_and_values_for_model( instance, job, table, model, prefix=None): if prefix: prefix += '__' else: prefix = '' perms = permissions(job.user, instance, model) extra_select = {} prefixed_names = [] dummy_instance = safe_get_model_class(model)() for perm in (perm for perm in perms if perm.permission_level >= FieldPermission.READ_ONLY): field_name = perm.field_name prefixed_name = prefix + field_name if field_name.startswith('udf:'): name = field_name[4:] extra_select[prefixed_name] = "%s.udfs->'%s'" % (table, name) else: if not model_hasattr(dummy_instance, field_name): # Exception will be raised downstream if you look for # a field on a model that no longer exists but still # has a stale permission record. Here we check for that # case and don't include the field if it does not exist. continue prefixed_names.append(prefixed_name) return (extra_select, prefixed_names)
def get_model(self, _, object_name, instance=None): Model = safe_get_model_class(to_model_name(object_name)) if instance and hasattr(Model, 'instance'): return Model(instance=instance) else: return Model()
def get_model(self, _, object_name, instance=None): Model = safe_get_model_class(to_model_name(object_name)) if instance and hasattr(Model, "instance"): return Model(instance=instance) else: return Model()
def get_model(self, _, model_name, instance=None): Model = safe_get_model_class(model_name.capitalize()) if instance and hasattr(Model, 'instance'): return Model(instance=instance) else: return Model()
def _values_for_model(instance, job, table, model, select, select_params, prefix=None): if prefix: prefix += '__' else: prefix = '' prefixed_names = [] model_class = safe_get_model_class(model) dummy_instance = model_class() if hasattr(model_class, 'instance'): dummy_instance.instance = instance for field_name in dummy_instance.visible_fields(job.user): prefixed_name = prefix + field_name if field_name.startswith('udf:'): name = field_name[4:] if name in model_class.collection_udf_settings.keys(): field_definition_id = None for udfd in udf_defs(instance, model): if udfd.iscollection and udfd.name == name: field_definition_id = udfd.id if field_definition_id is None: continue select[prefixed_name] = (""" WITH formatted_data AS ( SELECT concat('(', data, ')') as fdata FROM %s WHERE field_definition_id = %s and model_id = %s.id ) SELECT array_to_string(array_agg(fdata), ', ', '*') FROM formatted_data """ % (UserDefinedCollectionValue._meta.db_table, field_definition_id, table)) else: select[prefixed_name] = "{0}.udfs->%s".format(table) select_params.append(name) else: if not model_hasattr(dummy_instance, field_name): # Exception will be raised downstream if you look for # a field on a model that no longer exists but still # has a stale permission record. Here we check for that # case and don't include the field if it does not exist. continue prefixed_names.append(prefixed_name) return prefixed_names
def _values_for_model(instance, job, table, model, select, select_params, prefix=None): if prefix: prefix += "__" else: prefix = "" prefixed_names = [] model_class = safe_get_model_class(model) dummy_instance = model_class() for field_name in ( perm.field_name for perm in field_permissions(job.user, instance, model) if perm.permission_level >= FieldPermission.READ_ONLY ): prefixed_name = prefix + field_name if field_name.startswith("udf:"): name = field_name[4:] if name in model_class.collection_udf_settings.keys(): field_definition_id = None for udfd in udf_defs(instance, model): if udfd.iscollection and udfd.name == name: field_definition_id = udfd.id if field_definition_id is None: continue select[ prefixed_name ] = """ WITH formatted_data AS ( SELECT concat('(', data, ')') as fdata FROM %s WHERE field_definition_id = %s and model_id = %s.id ) SELECT array_to_string(array_agg(fdata), ', ', '*') FROM formatted_data """ % ( UserDefinedCollectionValue._meta.db_table, field_definition_id, table, ) else: select[prefixed_name] = "{0}.udfs->%s".format(table) select_params.append(name) else: if not model_hasattr(dummy_instance, field_name): # Exception will be raised downstream if you look for # a field on a model that no longer exists but still # has a stale permission record. Here we check for that # case and don't include the field if it does not exist. continue prefixed_names.append(prefixed_name) return prefixed_names
def extra_select_and_values_for_model( instance, job, table, model, prefix=None): if prefix: prefix += '__' else: prefix = '' perms = permissions(job.user, instance, model) extra_select = {} prefixed_names = [] dummy_instance = safe_get_model_class(model)() for perm in (perm for perm in perms if perm.permission_level >= FieldPermission.READ_ONLY): field_name = perm.field_name prefixed_name = prefix + field_name if field_name in _UDFC_FIELDS: field_definition_id = None for udfd in udf_defs(instance, model): if udfd.iscollection and udfd.name == field_name[4:]: field_definition_id = udfd.id if field_definition_id is None: continue extra_select[prefixed_name] = ( """ WITH formatted_data AS ( SELECT concat('(', data, ')') as fdata FROM %s WHERE field_definition_id = %s and model_id = %s.id ) SELECT array_to_string(array_agg(fdata), ', ', '*') FROM formatted_data """ % (UserDefinedCollectionValue._meta.db_table, field_definition_id, table)) elif field_name.startswith('udf:'): name = field_name[4:] extra_select[prefixed_name] = "%s.udfs->'%s'" % (table, name) else: if not model_hasattr(dummy_instance, field_name): # Exception will be raised downstream if you look for # a field on a model that no longer exists but still # has a stale permission record. Here we check for that # case and don't include the field if it does not exist. continue prefixed_names.append(prefixed_name) return (extra_select, prefixed_names)
def get_disabled_fields(group): model_name = to_model_name(group['model']) Model = safe_get_model_class(model_name) mobj = Model(instance=instance) model_fields = {field for field in mobj.tracked_fields if _should_show_field(Model, field)} model_fields = {'%s.%s' % (group['model'], f) for f in model_fields} disabled_fields = model_fields - set(group['field_keys']) return sorted(disabled_fields)
def instance_info(request, instance): """ Get all the info we need about a given instance If 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 perms = {} for fp in role.fieldpermission_set.all(): model = fp.model_name.lower() if fp.allows_reads: if model not in perms: perms[model] = [] if 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) perms[model].append( { "data_type": data_type, "choices": choices, "units": units, "digits": digits, "can_write": fp.allows_writes, "display_name": fp.display_field_name, "field_name": fp.field_name, } ) info = _instance_info_dict(instance) info["fields"] = perms info["search"] = instance.advanced_search_fields return info
def create_udfc(instance, model, udfc_name): from treemap.udf import UserDefinedFieldDefinition from treemap.util import safe_get_model_class clz = safe_get_model_class(model) udfc, __ = UserDefinedFieldDefinition.objects.get_or_create( instance_id=instance.pk, model_type=model, datatype=json.dumps(clz.collection_udf_settings[udfc_name] .get('defaults')), iscollection=True, name=udfc_name) return udfc
def _get_fields(instance, model_name): Model = safe_get_model_class(model_name) mobj = Model(instance=instance) udfs = {udf.canonical_name for udf in udf_defs(instance, model_name) if not udf.iscollection} concrete_fields = { f.name for f in mobj._meta.get_fields(include_parents=False) if _should_show_field(Model, f.name) and not f.is_relation} model_fields = concrete_fields | udfs model_fields = {'%s.%s' % (to_object_name(model_name), f) for f in model_fields} return model_fields
def get_context_for_model(model_name): model_fields = fields_by_model[model_name] enabled, disabled = get_enabled_and_disabled_fields(model_name, model_fields) display_name = safe_get_model_class(model_name).display_name(instance) return { 'field_keys': enabled, 'disabled_fields': disabled, 'header': _('%(model)s Filters') % {'model': display_name}, 'category': model_name, }
def get_disabled_fields(group): model_name = to_model_name(group['model']) Model = safe_get_model_class(model_name) mobj = Model(instance=instance) model_fields = { field for field in mobj.tracked_fields if _should_show_field(Model, field) } model_fields = {'%s.%s' % (group['model'], f) for f in model_fields} disabled_fields = model_fields - set(group['field_keys']) return sorted(disabled_fields)
def create_udf(instance, model, udfc_name): from treemap.udf import UserDefinedFieldDefinition from treemap.util import safe_get_model_class clz = safe_get_model_class(model) udfc_settings = clz.udf_settings[udfc_name] udfc, __ = UserDefinedFieldDefinition.objects.get_or_create( instance_id=instance.pk, model_type=model, iscollection=udfc_settings.get("iscollection"), datatype=json.dumps(udfc_settings.get("defaults")), name=udfc_name, ) return udfc
def get_context_for_model(model_name): model_fields = fields_by_model[model_name] enabled, disabled = get_enabled_and_disabled_fields( model_name, model_fields) display_name = safe_get_model_class(model_name).display_name(instance) return { 'field_keys': enabled, 'disabled_fields': disabled, 'header': _('%(model)s Filters') % { 'model': display_name }, 'category': model_name, }
def get_or_create_udf(instance, model, udfc_name): from treemap.udf import UserDefinedFieldDefinition from treemap.util import safe_get_model_class clz = safe_get_model_class(model) udfc_settings = clz.udf_settings[udfc_name] kwargs = { 'instance_id': instance.pk, 'model_type': model, 'iscollection': udfc_settings.get('iscollection'), 'name': udfc_name, } try: udfc = UserDefinedFieldDefinition.objects.get(**kwargs) except UserDefinedFieldDefinition.DoesNotExist: kwargs['datatype'] = json.dumps(udfc_settings.get('defaults')) udfc = UserDefinedFieldDefinition.objects.create(**kwargs) return udfc
def safe_get_udf_model_class(model_string): """ In a couple of cases we want to be able to convert a string into a valid django model class. For instance, if we have 'Plot' we want to get the actual class for 'treemap.models.Plot' in a safe way. This function returns the class represented by the given model if it exists in 'treemap.models' and the class's objects are a subtype of UDFModel """ model_class = safe_get_model_class(model_string) # It must have be a UDF subclass if not isinstance(model_class(), UDFModel): raise ValidationError(_('invalid model type - must subclass UDFModel')) return model_class
def _get_fields(instance, model_name): Model = safe_get_model_class(model_name) mobj = Model(instance=instance) udfs = { udf.canonical_name for udf in udf_defs(instance, model_name) if not udf.iscollection } concrete_fields = { f.name for f in mobj._meta.get_fields(include_parents=False) if _should_show_field(Model, f.name) and not f.is_relation } model_fields = concrete_fields | udfs model_fields = { '%s.%s' % (to_object_name(model_name), f) for f in model_fields } return model_fields
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 safe_get_udf_model_class(model_string): """ In a couple of cases we want to be able to convert a string into a valid django model class. For instance, if we have 'Plot' we want to get the actual class for 'treemap.models.Plot' in a safe way. This function returns the class represented by the given model if it exists in 'treemap.models' and the class's objects are a subtype of UDFModel """ model_class = safe_get_model_class(model_string) # It must have be a UDF subclass if not isinstance(model_class(), UDFModel): raise ValidationError(trans('invalid model type - must subclass ' 'UDFModel')) return model_class
def instance_info(request, instance): """ Get all the info we need about a given instance If 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 perms = {} fields_to_allow = instance.mobile_api_fields for fp in role.fieldpermission_set.all(): model = fp.model_name.lower() if fields_to_allow and \ fp.field_name not in fields_to_allow.get(model, []): continue if fp.allows_reads: if model not in perms: perms[model] = [] if 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 = get_conversion_factor( instance, model, fp.field_name) except KeyError: pass perms[model].append({ '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': '%s.%s' % (model, fp.field_name) }) info = _instance_info_dict(instance) info['fields'] = perms info['search'] = instance.mobile_search_fields 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 If 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 perms = {} collection_udfs = instance.userdefinedfielddefinition_set\ .filter(iscollection=True) collection_udf_dict = { "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf for udf in collection_udfs } for fp in role.fieldpermission_set.all(): 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 = 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 = get_conversion_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 } info = _instance_info_dict(instance) info['fields'] = perms info['field_key_groups'] = instance.mobile_api_fields info['search'] = instance.mobile_search_fields 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.userdefinedfielddefinition_set\ .filter(iscollection=True) 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 = get_conversion_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'] = instance.mobile_search_fields 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.userdefinedfielddefinition_set\ .filter(iscollection=True) 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 = 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 = get_conversion_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 } info = _instance_info_dict(instance) info['fields'] = perms info['field_key_groups'] = instance.mobile_api_fields info['search'] = instance.mobile_search_fields 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