コード例 #1
0
    def build_diff_of_subitem_dict(self, earlier_item, later_item,
                                   subitem_model) -> List[Dict]:
        difference_dict = {}

        for field, earlier_value in earlier_item.items():
            if field == 'id':
                pass
            else:
                later_value = later_item[field]
                if not self.raw:
                    earlier_value = strip_tags(str(earlier_value))
                    later_value = strip_tags(str(later_value))

                if earlier_value is None:
                    # Can't perform a diff on a null value
                    earlier_value = 'None'

                if later_value is None:
                    later_value = 'None'

                difference_dict[field] = {
                    'is_html': self.is_field_html(field, subitem_model),
                    'diff': self.perform_diff_on_field(earlier_value,
                                                       later_value)
                }
        return [difference_dict]
コード例 #2
0
    def generate_diff(self, earlier_dict, later_dict):
        """
        Returns a dictionary containing a list of tuples with the differences per field.
        The first element of the tuple specifies if it is an insertion (1), a deletion (-1), or an equality (0).
        Example:
        {field: [(0, hello), (1, world)]}
        """
        field_to_diff = {}

        # Only get the shared field names
        field_names = list(set(earlier_dict.keys()).intersection(set(later_dict.keys())))

        for field in earlier_dict:
            # Iterate through all fields in the dictionary
            show_field = field not in self.hidden_diff_fields and field in field_names
            if show_field:
                # Don't show fields like modified, which are set by the database
                earlier_value = earlier_dict[field]
                later_value = later_dict[field]

                if not self.both_fields_empty(earlier_value, later_value):
                    if isinstance(earlier_value, str) or isinstance(earlier_value, int):
                        # No special treatment required for strings and int
                        earlier = str(earlier_value)
                        later = str(later_value)

                        if not self.raw:
                            # Strip tags if it's not raw
                            earlier = strip_tags(earlier)
                            later = strip_tags(later)

                        is_html_field = self.is_field_html(field, self.model)

                        field_to_diff[field] = {'user_friendly_name': field.title(),
                                                'subitem': False,
                                                'is_html': is_html_field,
                                                'diffs': self.perform_diff_on_field(earlier, later)}

                    elif isinstance(earlier_value, dict):
                        # It's a single subitem
                        subitem_model = self.get_model_from_foreign_key_field(self.model, self.clean_field(field))
                        field_to_diff[field] = {
                            'user_friendly_name': self.get_user_friendly_field_name(field, self.model),
                            'subitem': True,
                            'diffs': self.build_diff_of_subitem_dict(earlier_value, later_value,
                                                                     subitem_model)
                        }
                    elif isinstance(earlier_value, list):
                        # It's a list of subitems
                        subitem_model = self.get_model_from_foreign_key_field(self.model, field)

                        field_to_diff[field] = {
                            'user_friendly_name': self.get_user_friendly_field_name(field, self.model),
                            'subitem': True,
                            'diffs': self.build_diff_of_subitems(earlier_value, later_value, subitem_model)}

        return field_to_diff
コード例 #3
0
    def generate_diff_for_added_or_removed_fields(self, ids, values, subitem_model, added=True):
        """ Generates the diff for fields that have been added/removed from a concept comparision"""
        differences = []

        for id in ids:
            item = values[id]
            difference_dict = {}

            for field, value in item.items():
                if field == 'id':
                    pass
                else:
                    if not self.raw:
                        value = strip_tags(str(value))
                    # Because DiffMatchPatch returns a list of tuples of diffs
                    # for consistent display we also return a list of tuples of diffs

                    is_html = False
                    if subitem_model is CustomValue:
                        custom_field_id = item['field']
                        if custom_field_id in self.get_html_custom_field_ids() and field == 'content':
                            is_html = True
                    else:
                        is_html = self.is_field_html(field, subitem_model)

                    if added:
                        difference_dict[field] = {'is_html': is_html,
                                                  'diff': [(1, value)]}
                    else:
                        difference_dict[field] = {'is_html': is_html,
                                                  'diff': [(-1, value)]}
            differences.append(difference_dict)
        return differences
コード例 #4
0
def zws(string):
    # Adds a zerowidth space before an em-dash
    """
    ``zws`` or "zero width space" is used to insert a soft break near em-dashed.
    Since em-dashs are commonly used in Data Element Concept names, this helps them wrap
    in the right places.

    For example::

        <h1>{% zws item.name %}</h1>

    """
    from aristotle_mdr.utils.utils import strip_tags
    return mark_safe(strip_tags(string.replace("—", "&shy;—")))
コード例 #5
0
    def build_diff_of_item(self, earlier_item, later_item,
                           subitem_model) -> Dict[str, Dict]:
        """Function that performs the actual comparision of a subitem"""
        difference_dict = {}

        for field, earlier_value in earlier_item.items():
            if field == 'id':
                # Don't compare ID
                pass
            else:
                later_value = later_item[field]

                earlier_value = str(earlier_value)
                later_value = str(later_value)

                if not self.raw:
                    earlier_value = strip_tags(earlier_value)
                    later_value = strip_tags(later_value)

                # Custom logic to determine if CustomValue field is HTML
                is_html = False
                if subitem_model is CustomValue:
                    is_html = self.is_custom_field_html(field, later_item)
                else:
                    is_html = self.is_field_html(field, subitem_model)

                difference = [(difference_code,
                               self.replace_item_id(subitem_model, field,
                                                    difference))
                              for difference_code, difference in
                              self.diff_field(earlier_value, later_value)]

                difference_dict[field] = {
                    'is_html': is_html,
                    'diff': difference
                }
        return difference_dict
コード例 #6
0
    def build_diff_of_subitems(self, earlier_values, later_values, subitem_model) -> List[Dict]:
        """
        Given a list of dictionaries containing representations of objects, iterates through and returns a list of
        difference dictionaries per field
        Example:
            [{'field': [(0, hello), (1, world)], 'other_field': [(0, goodbye), (-1, world)]]
        """
        differences: list = []

        if not self.both_fields_empty(earlier_values, later_values):
            key = self.get_subitem_key(subitem_model)

            earlier_items = {item[key]: item for item in earlier_values}
            earlier_items = self.replace_id_with_names(subitem_model, earlier_items)

            later_items = {item[key]: item for item in later_values}
            later_items = self.replace_id_with_names(subitem_model, later_items)

            # Items that are in the later items but not the earlier items have been 'added'
            added_ids = set(later_items.keys()) - set(earlier_items.keys())
            added_items = self.generate_diff_for_added_or_removed_fields(added_ids, later_items,
                                                                         subitem_model, added=True)
            if added_items:
                differences.extend(added_items)

            # Items that are in the earlier items but not the later items have been 'removed'
            removed_ids = set(earlier_items.keys()) - set(later_items.keys())
            removed_items = self.generate_diff_for_added_or_removed_fields(removed_ids, earlier_items,
                                                                           subitem_model, added=False)
            if removed_items:
                differences.extend(removed_items)

            # Items with IDs that are present in both earlier and later data have been changed,
            # so we want to perform a field-by-field dict comparision.
            changed_ids = set(earlier_items).intersection(set(later_items))

            for id in changed_ids:
                earlier_item = earlier_items[id]
                later_item = later_items[id]

                difference_dict = {}

                for field, earlier_value in earlier_item.items():
                    if field == 'id':
                        pass
                    else:
                        later_value = later_item[field]

                        earlier_value = str(earlier_value)
                        later_value = str(later_value)

                        if not self.raw:
                            earlier_value = strip_tags(earlier_value)
                            later_value = strip_tags(later_value)

                        # Custom logic to determine if CustomValue field is HTML
                        is_html = False
                        if subitem_model is CustomValue:
                            custom_field_id = later_item['field']
                            if custom_field_id in self.get_html_custom_field_ids() and field == 'content':
                                is_html = True
                        else:
                            is_html = self.is_field_html(field, subitem_model)

                        difference_dict[field] = {'is_html': is_html,
                                                  'diff': self.perform_diff_on_field(earlier_value, later_value)}
                if difference_dict:
                    differences.append(difference_dict)

        return differences