def __get_properties(self, entity_id=None, entity_definition_keyname=None, dataproperty=None, full_definition=False, only_public=False, sharing_key=None):
        """
        Get Entity properties. entity_id can be single ID or list of IDs.
        * full_definition - All metadata for entity and properties is fetched, if True
        """
        items = None
        if entity_id:
            if type(entity_id) is not list:
                entity_id = [entity_id]

            if self.__user_id and only_public == False:
                rights = '(SELECT relationship_definition_keyname FROM relationship WHERE entity_id = entity.id AND is_deleted = 0 AND related_entity_id = %s AND relationship_definition_keyname IN (\'viewer\', \'expander\', \'editor\', \'owner\') LIMIT 1)' % self.__user_id
                public = ''
            elif sharing_key:
                rights = 'FALSE'
                public = 'AND entity.sharing_key = \'%s\'' % sharing_key
            else:
                rights = 'FALSE'
                public = 'AND entity.sharing = \'public\' AND property_definition.public = 1'

            datapropertysql = ''
            if dataproperty:
                if type(dataproperty) is not list:
                    dataproperty = [dataproperty]
                datapropertysql = 'AND property_definition.dataproperty IN (%s)' % ','.join(['\'%s\'' % x for x in dataproperty])

            sql = """
                SELECT
                    entity_definition.keyname                       AS entity_definition_keyname,
                    entity.id                                       AS entity_id,
                    entity.created                                  AS entity_created,
                    entity.changed                                  AS entity_changed,
                    entity.sharing                                  AS entity_sharing,
                    entity.sharing_key                              AS entity_sharing_key,
                    %(rights)s                                      AS entity_right,
                    entity.sort                                     AS entity_sort_value,
                    property_definition.keyname                     AS property_keyname,
                    property_definition.ordinal                     AS property_ordinal,
                    property_definition.formula                     AS property_formula,
                    property_definition.executable                  AS property_executable,
                    property_definition.datatype                    AS property_datatype,
                    property_definition.dataproperty                AS property_dataproperty,
                    property_definition.mandatory                   AS property_mandatory,
                    property_definition.multilingual                AS property_multilingual,
                    property_definition.multiplicity                AS property_multiplicity,
                    property_definition.public                      AS property_public,
                    property_definition.readonly                    AS property_readonly,
                    property_definition.visible                     AS property_visible,
                    property.id                                     AS value_id,
                    property.id                                     AS value_ordinal,
                    property.created                                AS value_created,
                    property.created_by                             AS value_created_by,
                    property.value_display                          AS value_display,
                    property.value_formula                          AS value_formula,
                    property.value_string                           AS value_string,
                    property.value_text                             AS value_text,
                    property.value_integer                          AS value_integer,
                    property.value_decimal                          AS value_decimal,
                    property.value_boolean                          AS value_boolean,
                    property.value_datetime                         AS value_datetime,
                    property.value_entity                           AS value_entity,
                    property.value_counter                          AS value_counter,
                    property.value_reference                        AS value_reference,
                    property.value_file                             AS value_file
                FROM
                    entity,
                    entity_definition,
                    property,
                    property_definition
                WHERE property.entity_id = entity.id
                AND entity_definition.keyname = entity.entity_definition_keyname
                AND property_definition.keyname = property.property_definition_keyname
                AND entity_definition.keyname = property_definition.entity_definition_keyname
                AND (property.language = '%(language)s' OR property.language IS NULL)
                AND entity.id IN (%(idlist)s)
                AND entity.is_deleted = 0
                AND property.is_deleted = 0
                %(public)s
                %(datapropertysql)s
                ORDER BY
                    entity_definition.keyname,
                    entity.created DESC;
            """ % {'language': self.get_user_locale().code, 'public': public, 'idlist': ','.join(map(str, entity_id)), 'datapropertysql': datapropertysql, 'rights': rights}
            # logging.debug(sql)

            items = {}
            for row in self.db_query(sql):
                if row.get('entity_sharing') == 'private' and not row.get('entity_right') and not sharing_key:
                    continue
                if row.get('entity_sharing') in ['domain', 'public'] and row.get('entity_right') not in ['viewer', 'expander', 'editor', 'owner'] and row.get('property_public') != 1 and not sharing_key:
                    continue

                #Entity
                items.setdefault('item_%s' % row.get('entity_id'), {})['definition_keyname'] = row.get('entity_definition_keyname')
                items.setdefault('item_%s' % row.get('entity_id'), {})['id'] = row.get('entity_id')
                items.setdefault('item_%s' % row.get('entity_id'), {})['label'] = self.__get_system_translation(field='label', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['label_plural'] = self.__get_system_translation(field='label_plural', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['description'] = self.__get_system_translation(field='description', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['sort'] = self.__get_system_translation(field='sort', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['sort_value'] = row.get('entity_sort_value')
                items.setdefault('item_%s' % row.get('entity_id'), {})['created'] = row.get('entity_created')
                items.setdefault('item_%s' % row.get('entity_id'), {})['changed'] = row.get('entity_changed')
                items.setdefault('item_%s' % row.get('entity_id'), {})['displayname'] = self.__get_system_translation(field='displayname', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['displayinfo'] = self.__get_system_translation(field='displayinfo', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['displaytable'] = self.__get_system_translation(field='displaytable', entity_definition_keyname=row.get('entity_definition_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {})['sharing'] = row.get('entity_sharing')
                items.setdefault('item_%s' % row.get('entity_id'), {})['sharing_key'] = row.get('entity_sharing_key')
                items.setdefault('item_%s' % row.get('entity_id'), {})['right'] = row.get('entity_right')
                items.setdefault('item_%s' % row.get('entity_id'), {})['ordinal'] = row.get('entity_created') if row.get('entity_created') else datetime.datetime.now()

                #Property
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['keyname'] = row.get('property_keyname')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['fieldset'] = self.__get_system_translation(field='fieldset', property_definition_keyname=row.get('property_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['label'] = self.__get_system_translation(field='label', property_definition_keyname=row.get('property_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['label_plural'] = self.__get_system_translation(field='label_plural', property_definition_keyname=row.get('property_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['description'] = self.__get_system_translation(field='description', property_definition_keyname=row.get('property_keyname'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['datatype'] = row.get('property_datatype')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['dataproperty'] = row.get('property_dataproperty')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['mandatory'] = bool(row.get('property_mandatory'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['multilingual'] = bool(row.get('property_multilingual'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['multiplicity'] = row.get('property_multiplicity')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['ordinal'] = row.get('property_ordinal')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['formula'] = bool(row.get('property_formula'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['executable'] = bool(row.get('property_executable'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['public'] = bool(row.get('property_public'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['readonly'] = bool(row.get('property_readonly'))
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {})['visible'] = bool(row.get('property_visible'))

                #Value
                value = row.get('value_display') if row.get('value_display') else ''

                if row.get('property_formula') == 1:
                    db_value = row.get('value_formula')
                elif row.get('property_datatype') == 'string':
                    db_value = row.get('value_string')
                elif row.get('property_datatype') == 'text':
                    db_value = row.get('value_text')
                    value = row.get('value_text') if row.get('value_text') else ''
                elif row.get('property_datatype') == 'integer':
                    db_value = row.get('value_integer')
                elif row.get('property_datatype') == 'decimal':
                    db_value = row.get('value_decimal')
                elif row.get('property_datatype') == 'date':
                    db_value = row.get('value_datetime')
                elif row.get('property_datatype') == 'datetime':
                    db_value = row.get('value_datetime')
                elif row.get('property_datatype') == 'reference':
                    db_value = row.get('value_reference')
                elif row.get('property_datatype') == 'file':
                    db_value = row.get('value_file')
                elif row.get('property_datatype') == 'boolean':
                    db_value = row.get('value_boolean')
                elif row.get('property_datatype') == 'counter':
                    db_value = row.get('value_counter')
                elif row.get('property_datatype') == 'counter-value':
                    db_value = row.get('value_string')
                else:
                    db_value = ''
                    value = 'X'

                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['id'] = row.get('value_id')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['ordinal'] = row.get('value_ordinal')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['value'] = value
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['db_value'] = db_value
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['created'] = row.get('value_created')
                items.setdefault('item_%s' % row.get('entity_id'), {}).setdefault('properties', {}).setdefault('%s' % row.get('property_dataproperty'), {}).setdefault('values', {}).setdefault('value_%s' % row.get('value_id'), {})['created_by'] = row.get('value_created_by')

        if not items:
            if not full_definition:
                return []

            if entity_definition_keyname:
                if type(entity_definition_keyname) is not list:
                    entity_definition_keyname = [entity_definition_keyname]

                items = {}
                for e in entity_definition_keyname:
                    items.setdefault('item_%s' % e, {})['definition_keyname'] = e
                    items.setdefault('item_%s' % e, {})['ordinal'] = 'X'

        for key, value in items.iteritems():
            if value.get('id', None):
                items[key] = dict(items[key].items() + self.__get_displayfields(value).items())
                items[key]['displaypicture'] = self.__get_picture_url(value['id'], value['definition_keyname'])

            items[key]['completed'] = True
            for d in self.get_definition(entity_definition_keyname=value['definition_keyname']):
                if not value.get('id', None):
                    items[key]['displayname'] = d['entity_label']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['keyname'] = d['property_keyname']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['fieldset'] = d['property_fieldset']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['label'] = d['property_label']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['label_plural'] = d['property_label_plural']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['description'] = d['property_description']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['datatype'] = d['property_datatype']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['dataproperty'] = d['property_dataproperty']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['mandatory'] = d['property_mandatory']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['multilingual'] = d['property_multilingual']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['multiplicity'] = d['property_multiplicity']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['ordinal'] = d['property_ordinal']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['public'] = d['property_public']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['readonly'] = d['property_readonly']
                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['visible'] = d['property_visible']

                if d['property_mandatory'] and len(value.get('properties', {}).get('%s' % d['property_dataproperty'], {}).get('values', {}).values()) < 1:
                    items[key]['completed'] = False

                if full_definition:
                    if not d['property_multiplicity'] or d['property_multiplicity'] > len(value.get('properties', {}).get('%s' % d['property_dataproperty'], {}).get('values', {}).values()):
                        items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {}).setdefault('values', {})['value_new'] = {'id': '', 'ordinal': 'X', 'value': '', 'db_value': ''}
                    if not d['property_multiplicity'] or d['property_multiplicity'] > len(value.get('properties', {}).get('%s' % d['property_dataproperty'], {}).get('values', {}).values()):
                        items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['can_add_new'] = True
                    else:
                        items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {})['can_add_new'] = False

                    if d['property_classifier_id'] and d['property_datatype'] != 'reference':
                        for c in self.get_entities(entity_definition_keyname=d['property_classifier_id'], only_public=True):
                            if c.get('id', None):
                                items[key].setdefault('properties', {}).setdefault('%s' % d['property_dataproperty'], {}).setdefault('select', []).append({'id': c.get('id', ''), 'label': c.get('displayname', '')})

            for p_key, p_value in value.get('properties', {}).iteritems():
                if p_value.get('values'):
                    items[key]['properties'][p_key]['values'] = sorted(p_value.get('values', {}).values(), key=itemgetter('ordinal'))
                if p_value['datatype'] == 'reference':
                    reference_definition = self.db_get('SELECT classifying_entity_definition_keyname FROM property_definition WHERE keyname = %s LIMIT 1;', p_value['keyname'])
                    if reference_definition:
                        if reference_definition.get('classifying_entity_definition_keyname'):
                            items[key]['properties'][p_key]['reference_definition'] = reference_definition.get('classifying_entity_definition_keyname')
                if p_value['datatype'] == 'file':
                    for f_key, f_value in enumerate(p_value.get('values', {})):
                        if not f_value.get('db_value'):
                            continue
                        file_result = self.db_get('SELECT md5, filesize, created FROM file WHERE id = %s;', f_value.get('db_value'))
                        if not file_result:
                            continue
                        items[key]['properties'][p_key]['values'][f_key]['md5'] = file_result.get('md5')
                        items[key]['properties'][p_key]['values'][f_key]['filesize'] = file_result.get('filesize')
                        items[key]['properties'][p_key]['values'][f_key]['created'] = file_result.get('created')

        return items.values()
dataset/ETHPy150Open argoroots/Entu/app/main/db.py/Entity.__get_properties/original