示例#1
0
    def get_attrs(self, item_list, user):
        from sentry.plugins.base import plugins
        from sentry.integrations import IntegrationFeatures
        from sentry.models import PlatformExternalIssue

        GroupMeta.objects.populate_cache(item_list)

        attach_foreignkey(item_list, Group.project)

        if user.is_authenticated() and item_list:
            bookmarks = set(
                GroupBookmark.objects.filter(user=user, group__in=item_list).values_list(
                    "group_id", flat=True
                )
            )
            seen_groups = dict(
                GroupSeen.objects.filter(user=user, group__in=item_list).values_list(
                    "group_id", "last_seen"
                )
            )
            subscriptions = self._get_subscriptions(item_list, user)
        else:
            bookmarks = set()
            seen_groups = {}
            subscriptions = defaultdict(lambda: (False, None))

        assignees = {
            a.group_id: a.assigned_actor()
            for a in GroupAssignee.objects.filter(group__in=item_list)
        }
        resolved_assignees = Actor.resolve_dict(assignees)

        ignore_items = {g.group_id: g for g in GroupSnooze.objects.filter(group__in=item_list)}

        resolved_item_list = [i for i in item_list if i.status == GroupStatus.RESOLVED]
        if resolved_item_list:
            release_resolutions = {
                i[0]: i[1:]
                for i in GroupResolution.objects.filter(group__in=resolved_item_list).values_list(
                    "group", "type", "release__version", "actor_id"
                )
            }

            # due to our laziness, and django's inability to do a reasonable join here
            # we end up with two queries
            commit_results = list(
                Commit.objects.extra(
                    select={"group_id": "sentry_grouplink.group_id"},
                    tables=["sentry_grouplink"],
                    where=[
                        "sentry_grouplink.linked_id = sentry_commit.id",
                        "sentry_grouplink.group_id IN ({})".format(
                            ", ".join(six.text_type(i.id) for i in resolved_item_list)
                        ),
                        "sentry_grouplink.linked_type = %s",
                        "sentry_grouplink.relationship = %s",
                    ],
                    params=[int(GroupLink.LinkedType.commit), int(GroupLink.Relationship.resolves)],
                )
            )
            commit_resolutions = {
                i.group_id: d for i, d in zip(commit_results, serialize(commit_results, user))
            }
        else:
            release_resolutions = {}
            commit_resolutions = {}

        actor_ids = set(r[-1] for r in six.itervalues(release_resolutions))
        actor_ids.update(r.actor_id for r in six.itervalues(ignore_items))
        if actor_ids:
            users = list(User.objects.filter(id__in=actor_ids, is_active=True))
            actors = {u.id: d for u, d in zip(users, serialize(users, user))}
        else:
            actors = {}

        share_ids = dict(
            GroupShare.objects.filter(group__in=item_list).values_list("group_id", "uuid")
        )

        result = {}

        seen_stats = self._get_seen_stats(item_list, user)

        annotations_by_group_id = defaultdict(list)

        organization_id_list = list(set(item.project.organization_id for item in item_list))
        # if no groups, then we can't proceed but this seems to be a valid use case
        if not item_list:
            return {}
        if len(organization_id_list) > 1:
            # this should never happen but if it does we should know about it
            logger.warn(
                "Found multiple organizations for groups: %s, with orgs: %s"
                % ([item.id for item in item_list], organization_id_list)
            )

        # should only have 1 org at this point
        organization_id = organization_id_list[0]
        organization = Organization.objects.get_from_cache(id=organization_id)

        has_unhandled_flag = features.has(
            "organizations:unhandled-issue-flag", organization, actor=user
        )

        # find all the integration installs that have issue tracking
        for integration in Integration.objects.filter(organizations=organization_id):
            if not (
                integration.has_feature(IntegrationFeatures.ISSUE_BASIC)
                or integration.has_feature(IntegrationFeatures.ISSUE_SYNC)
            ):
                continue

            install = integration.get_installation(organization_id)
            local_annotations_by_group_id = (
                safe_execute(
                    install.get_annotations_for_group_list,
                    group_list=item_list,
                    _with_transaction=False,
                )
                or {}
            )
            merge_list_dictionaries(annotations_by_group_id, local_annotations_by_group_id)

        # find the external issues for sentry apps and add them in
        local_annotations_by_group_id = (
            safe_execute(
                PlatformExternalIssue.get_annotations_for_group_list,
                group_list=item_list,
                _with_transaction=False,
            )
            or {}
        )
        merge_list_dictionaries(annotations_by_group_id, local_annotations_by_group_id)

        snuba_stats = {}
        if has_unhandled_flag:
            snuba_stats = self._get_group_snuba_stats(item_list, seen_stats)

        for item in item_list:
            active_date = item.active_at or item.first_seen

            annotations = []
            annotations.extend(annotations_by_group_id[item.id])

            # add the annotations for plugins
            # note that the model GroupMeta where all the information is stored is already cached at the top of this function
            # so these for loops doesn't make a bunch of queries
            for plugin in plugins.for_project(project=item.project, version=1):
                safe_execute(plugin.tags, None, item, annotations, _with_transaction=False)
            for plugin in plugins.for_project(project=item.project, version=2):
                annotations.extend(
                    safe_execute(plugin.get_annotations, group=item, _with_transaction=False) or ()
                )

            resolution_actor = None
            resolution_type = None
            resolution = release_resolutions.get(item.id)
            if resolution:
                resolution_type = "release"
                resolution_actor = actors.get(resolution[-1])
            if not resolution:
                resolution = commit_resolutions.get(item.id)
                if resolution:
                    resolution_type = "commit"

            ignore_item = ignore_items.get(item.id)
            if ignore_item:
                ignore_actor = actors.get(ignore_item.actor_id)
            else:
                ignore_actor = None

            result[item] = {
                "id": item.id,
                "assigned_to": resolved_assignees.get(item.id),
                "is_bookmarked": item.id in bookmarks,
                "subscription": subscriptions[item.id],
                "has_seen": seen_groups.get(item.id, active_date) > active_date,
                "annotations": annotations,
                "ignore_until": ignore_item,
                "ignore_actor": ignore_actor,
                "resolution": resolution,
                "resolution_type": resolution_type,
                "resolution_actor": resolution_actor,
                "share_id": share_ids.get(item.id),
            }

            if has_unhandled_flag:
                result[item]["is_unhandled"] = bool(snuba_stats.get(item.id, {}).get("unhandled"))

            if seen_stats:
                result[item].update(seen_stats.get(item, {}))
        return result
示例#2
0
    def get_attrs(self, item_list, user):
        from sentry.plugins.base import plugins

        GroupMeta.objects.populate_cache(item_list)

        attach_foreignkey(item_list, Group.project)

        if user.is_authenticated() and item_list:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=user, group__in=item_list).values_list("group_id",
                                                                flat=True))
            seen_groups = dict(
                GroupSeen.objects.filter(user=user,
                                         group__in=item_list).values_list(
                                             "group_id", "last_seen"))
            subscriptions = self._get_subscriptions(item_list, user)
        else:
            bookmarks = set()
            seen_groups = {}
            subscriptions = defaultdict(lambda: (False, None))

        assignees = {
            a.group_id: a.assigned_actor()
            for a in GroupAssignee.objects.filter(group__in=item_list)
        }
        resolved_assignees = Actor.resolve_dict(assignees)

        ignore_items = {
            g.group_id: g
            for g in GroupSnooze.objects.filter(group__in=item_list)
        }

        resolved_item_list = [
            i for i in item_list if i.status == GroupStatus.RESOLVED
        ]
        if resolved_item_list:
            release_resolutions = {
                i[0]: i[1:]
                for i in GroupResolution.objects.filter(
                    group__in=resolved_item_list).values_list(
                        "group", "type", "release__version", "actor_id")
            }

            # due to our laziness, and django's inability to do a reasonable join here
            # we end up with two queries
            commit_results = list(
                Commit.objects.extra(
                    select={"group_id": "sentry_grouplink.group_id"},
                    tables=["sentry_grouplink"],
                    where=[
                        "sentry_grouplink.linked_id = sentry_commit.id",
                        "sentry_grouplink.group_id IN ({})".format(", ".join(
                            six.text_type(i.id) for i in resolved_item_list)),
                        "sentry_grouplink.linked_type = %s",
                        "sentry_grouplink.relationship = %s",
                    ],
                    params=[
                        int(GroupLink.LinkedType.commit),
                        int(GroupLink.Relationship.resolves)
                    ],
                ))
            commit_resolutions = {
                i.group_id: d
                for i, d in zip(commit_results, serialize(
                    commit_results, user))
            }
        else:
            release_resolutions = {}
            commit_resolutions = {}

        actor_ids = set(r[-1] for r in six.itervalues(release_resolutions))
        actor_ids.update(r.actor_id for r in six.itervalues(ignore_items))
        if actor_ids:
            users = list(User.objects.filter(id__in=actor_ids, is_active=True))
            actors = {u.id: d for u, d in zip(users, serialize(users, user))}
        else:
            actors = {}

        share_ids = dict(
            GroupShare.objects.filter(group__in=item_list).values_list(
                "group_id", "uuid"))

        result = {}

        seen_stats = self._get_seen_stats(item_list, user)

        for item in item_list:
            active_date = item.active_at or item.first_seen

            annotations = []
            for plugin in plugins.for_project(project=item.project, version=1):
                safe_execute(plugin.tags,
                             None,
                             item,
                             annotations,
                             _with_transaction=False)
            for plugin in plugins.for_project(project=item.project, version=2):
                annotations.extend(
                    safe_execute(plugin.get_annotations,
                                 group=item,
                                 _with_transaction=False) or ())

            from sentry.integrations import IntegrationFeatures

            for integration in Integration.objects.filter(
                    organizations=item.project.organization_id):
                if not (integration.has_feature(
                        IntegrationFeatures.ISSUE_BASIC)
                        or integration.has_feature(
                            IntegrationFeatures.ISSUE_SYNC)):
                    continue

                install = integration.get_installation(
                    item.project.organization_id)
                annotations.extend(
                    safe_execute(install.get_annotations,
                                 group=item,
                                 _with_transaction=False) or ())

            from sentry.models import PlatformExternalIssue

            annotations.extend(
                safe_execute(PlatformExternalIssue.get_annotations,
                             group=item,
                             _with_transaction=False) or ())

            resolution_actor = None
            resolution_type = None
            resolution = release_resolutions.get(item.id)
            if resolution:
                resolution_type = "release"
                resolution_actor = actors.get(resolution[-1])
            if not resolution:
                resolution = commit_resolutions.get(item.id)
                if resolution:
                    resolution_type = "commit"

            ignore_item = ignore_items.get(item.id)
            if ignore_item:
                ignore_actor = actors.get(ignore_item.actor_id)
            else:
                ignore_actor = None

            result[item] = {
                "assigned_to": resolved_assignees.get(item.id),
                "is_bookmarked": item.id in bookmarks,
                "subscription": subscriptions[item.id],
                "has_seen":
                seen_groups.get(item.id, active_date) > active_date,
                "annotations": annotations,
                "ignore_until": ignore_item,
                "ignore_actor": ignore_actor,
                "resolution": resolution,
                "resolution_type": resolution_type,
                "resolution_actor": resolution_actor,
                "share_id": share_ids.get(item.id),
            }

            result[item].update(seen_stats.get(item, {}))
        return result
示例#3
0
文件: group.py 项目: yan96in/sentry
    def get_attrs(self, item_list, user):
        from sentry.plugins import plugins

        GroupMeta.objects.populate_cache(item_list)

        attach_foreignkey(item_list, Group.project)

        if user.is_authenticated() and item_list:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', flat=True))
            seen_groups = dict(
                GroupSeen.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', 'last_seen'))
            subscriptions = self._get_subscriptions(item_list, user)
        else:
            bookmarks = set()
            seen_groups = {}
            subscriptions = defaultdict(lambda: (False, None))

        assignees = {
            a.group_id: a.assigned_actor()
            for a in GroupAssignee.objects.filter(group__in=item_list, )
        }
        resolved_assignees = Actor.resolve_dict(assignees)

        try:
            environment = self.environment_func()
        except Environment.DoesNotExist:
            user_counts = {}
            first_seen = {}
            last_seen = {}
            times_seen = {}
        else:
            project_id = item_list[0].project_id
            item_ids = [g.id for g in item_list]
            user_counts = tagstore.get_groups_user_counts(
                project_id,
                item_ids,
                environment_id=environment and environment.id,
            )
            first_seen = {}
            last_seen = {}
            times_seen = {}
            if environment is not None:
                environment_tagvalues = tagstore.get_group_list_tag_value(
                    project_id,
                    item_ids,
                    environment.id,
                    'environment',
                    environment.name,
                )
                for item_id, value in environment_tagvalues.items():
                    first_seen[item_id] = value.first_seen
                    last_seen[item_id] = value.last_seen
                    times_seen[item_id] = value.times_seen
            else:
                for item in item_list:
                    first_seen[item.id] = item.first_seen
                    last_seen[item.id] = item.last_seen
                    times_seen[item.id] = item.times_seen

        ignore_items = {
            g.group_id: g
            for g in GroupSnooze.objects.filter(group__in=item_list, )
        }

        resolutions = {
            i[0]: i[1:]
            for i in GroupResolution.objects.filter(group__in=item_list,
                                                    ).values_list(
                                                        'group',
                                                        'type',
                                                        'release__version',
                                                        'actor_id',
                                                    )
        }
        actor_ids = set(r[-1] for r in six.itervalues(resolutions))
        actor_ids.update(r.actor_id for r in six.itervalues(ignore_items))
        if actor_ids:
            users = list(
                User.objects.filter(
                    id__in=actor_ids,
                    is_active=True,
                ))
            actors = {
                u.id: d
                for u, d in itertools.izip(users, serialize(users, user))
            }
        else:
            actors = {}

        share_ids = dict(
            GroupShare.objects.filter(group__in=item_list, ).values_list(
                'group_id', 'uuid'))

        result = {}
        for item in item_list:
            active_date = item.active_at or item.first_seen

            annotations = []
            for plugin in plugins.for_project(project=item.project, version=1):
                safe_execute(plugin.tags,
                             None,
                             item,
                             annotations,
                             _with_transaction=False)
            for plugin in plugins.for_project(project=item.project, version=2):
                annotations.extend(
                    safe_execute(plugin.get_annotations,
                                 group=item,
                                 _with_transaction=False) or ())

            resolution = resolutions.get(item.id)
            if resolution:
                resolution_actor = actors.get(resolution[-1])
            else:
                resolution_actor = None

            ignore_item = ignore_items.get(item.id)
            if ignore_item:
                ignore_actor = actors.get(ignore_item.actor_id)
            else:
                ignore_actor = None

            result[item] = {
                'assigned_to': resolved_assignees.get(item.id),
                'is_bookmarked': item.id in bookmarks,
                'subscription': subscriptions[item.id],
                'has_seen':
                seen_groups.get(item.id, active_date) > active_date,
                'annotations': annotations,
                'user_count': user_counts.get(item.id, 0),
                'ignore_until': ignore_item,
                'ignore_actor': ignore_actor,
                'resolution': resolution,
                'resolution_actor': resolution_actor,
                'share_id': share_ids.get(item.id),
                'times_seen': times_seen.get(item.id, 0),
                'first_seen': first_seen.get(item.id),  # TODO: missing?
                'last_seen': last_seen.get(item.id),
            }
        return result
示例#4
0
文件: group.py 项目: Kayle009/sentry
    def get_attrs(self, item_list, user):
        from sentry.plugins import plugins

        GroupMeta.objects.populate_cache(item_list)

        attach_foreignkey(item_list, Group.project)

        if user.is_authenticated() and item_list:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', flat=True)
            )
            seen_groups = dict(
                GroupSeen.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', 'last_seen')
            )
            subscriptions = self._get_subscriptions(item_list, user)
        else:
            bookmarks = set()
            seen_groups = {}
            subscriptions = defaultdict(lambda: (False, None))

        assignees = {
            a.group_id: a.assigned_actor() for a in
            GroupAssignee.objects.filter(
                group__in=item_list,
            )
        }
        resolved_assignees = Actor.resolve_dict(assignees)

        ignore_items = {g.group_id: g for g in GroupSnooze.objects.filter(
            group__in=item_list,
        )}

        resolved_item_list = [i for i in item_list if i.status == GroupStatus.RESOLVED]
        if resolved_item_list:
            release_resolutions = {
                i[0]: i[1:]
                for i in GroupResolution.objects.filter(
                    group__in=resolved_item_list,
                ).values_list(
                    'group',
                    'type',
                    'release__version',
                    'actor_id',
                )
            }

            # due to our laziness, and django's inability to do a reasonable join here
            # we end up with two queries
            commit_results = list(Commit.objects.extra(
                select={
                    'group_id': 'sentry_grouplink.group_id',
                },
                tables=['sentry_grouplink'],
                where=[
                    'sentry_grouplink.linked_id = sentry_commit.id',
                    'sentry_grouplink.group_id IN ({})'.format(
                        ', '.join(six.text_type(i.id) for i in resolved_item_list)),
                    'sentry_grouplink.linked_type = %s',
                    'sentry_grouplink.relationship = %s',
                ],
                params=[
                    int(GroupLink.LinkedType.commit),
                    int(GroupLink.Relationship.resolves),
                ]
            ))
            commit_resolutions = {
                i.group_id: d for i, d in itertools.izip(commit_results, serialize(commit_results, user))
            }
        else:
            release_resolutions = {}
            commit_resolutions = {}

        actor_ids = set(r[-1] for r in six.itervalues(release_resolutions))
        actor_ids.update(r.actor_id for r in six.itervalues(ignore_items))
        if actor_ids:
            users = list(User.objects.filter(
                id__in=actor_ids,
                is_active=True,
            ))
            actors = {u.id: d for u, d in itertools.izip(users, serialize(users, user))}
        else:
            actors = {}

        share_ids = dict(GroupShare.objects.filter(
            group__in=item_list,
        ).values_list('group_id', 'uuid'))

        result = {}

        seen_stats = self._get_seen_stats(item_list, user)

        for item in item_list:
            active_date = item.active_at or item.first_seen

            annotations = []
            for plugin in plugins.for_project(project=item.project, version=1):
                safe_execute(plugin.tags, None, item, annotations, _with_transaction=False)
            for plugin in plugins.for_project(project=item.project, version=2):
                annotations.extend(
                    safe_execute(plugin.get_annotations, group=item, _with_transaction=False) or ()
                )

            from sentry.integrations import IntegrationFeatures
            for integration in Integration.objects.filter(
                    organizations=item.project.organization_id):
                if not (integration.has_feature(IntegrationFeatures.ISSUE_BASIC) or integration.has_feature(
                        IntegrationFeatures.ISSUE_SYNC)):
                    continue

                install = integration.get_installation(item.project.organization_id)
                annotations.extend(
                    safe_execute(install.get_annotations, group=item, _with_transaction=False) or ()
                )

            resolution_actor = None
            resolution_type = None
            resolution = release_resolutions.get(item.id)
            if resolution:
                resolution_type = 'release'
                resolution_actor = actors.get(resolution[-1])
            if not resolution:
                resolution = commit_resolutions.get(item.id)
                if resolution:
                    resolution_type = 'commit'

            ignore_item = ignore_items.get(item.id)
            if ignore_item:
                ignore_actor = actors.get(ignore_item.actor_id)
            else:
                ignore_actor = None

            result[item] = {
                'assigned_to': resolved_assignees.get(item.id),
                'is_bookmarked': item.id in bookmarks,
                'subscription': subscriptions[item.id],
                'has_seen': seen_groups.get(item.id, active_date) > active_date,
                'annotations': annotations,
                'ignore_until': ignore_item,
                'ignore_actor': ignore_actor,
                'resolution': resolution,
                'resolution_type': resolution_type,
                'resolution_actor': resolution_actor,
                'share_id': share_ids.get(item.id),
            }

            result[item].update(seen_stats.get(item, {}))
        return result
示例#5
0
    def get_attrs(self, item_list, user):
        from sentry.plugins import plugins

        GroupMeta.objects.populate_cache(item_list)

        attach_foreignkey(item_list, Group.project)

        if user.is_authenticated() and item_list:
            bookmarks = set(
                GroupBookmark.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', flat=True))
            seen_groups = dict(
                GroupSeen.objects.filter(
                    user=user,
                    group__in=item_list,
                ).values_list('group_id', 'last_seen'))
            subscriptions = self._get_subscriptions(item_list, user)
        else:
            bookmarks = set()
            seen_groups = {}
            subscriptions = defaultdict(lambda: (False, None))

        assignees = {
            a.group_id: a.assigned_actor()
            for a in GroupAssignee.objects.filter(group__in=item_list, )
        }
        resolved_assignees = Actor.resolve_dict(assignees)

        try:
            environment = self.environment_func()
        except Environment.DoesNotExist:
            user_counts = {}
            first_seen = {}
            last_seen = {}
            times_seen = {}
        else:
            project_id = item_list[0].project_id
            item_ids = [g.id for g in item_list]
            user_counts = tagstore.get_groups_user_counts(
                project_id,
                item_ids,
                environment_id=environment and environment.id,
            )
            first_seen = {}
            last_seen = {}
            times_seen = {}
            if environment is not None:
                environment_tagvalues = tagstore.get_group_list_tag_value(
                    project_id,
                    item_ids,
                    environment.id,
                    'environment',
                    environment.name,
                )
                for item_id, value in environment_tagvalues.items():
                    first_seen[item_id] = value.first_seen
                    last_seen[item_id] = value.last_seen
                    times_seen[item_id] = value.times_seen
            else:
                for item in item_list:
                    first_seen[item.id] = item.first_seen
                    last_seen[item.id] = item.last_seen
                    times_seen[item.id] = item.times_seen

        ignore_items = {
            g.group_id: g
            for g in GroupSnooze.objects.filter(group__in=item_list, )
        }

        resolved_item_list = [
            i for i in item_list if i.status == GroupStatus.RESOLVED
        ]
        if resolved_item_list:
            release_resolutions = {
                i[0]: i[1:]
                for i in GroupResolution.objects.filter(
                    group__in=resolved_item_list, ).values_list(
                        'group',
                        'type',
                        'release__version',
                        'actor_id',
                    )
            }

            # due to our laziness, and django's inability to do a reasonable join here
            # we end up with two queries
            commit_results = list(
                Commit.objects.extra(
                    select={
                        'group_id': 'sentry_grouplink.group_id',
                    },
                    tables=['sentry_grouplink'],
                    where=[
                        'sentry_grouplink.linked_id = sentry_commit.id',
                        'sentry_grouplink.group_id IN ({})'.format(', '.join(
                            six.text_type(i.id) for i in resolved_item_list)),
                        'sentry_grouplink.linked_type = %s',
                        'sentry_grouplink.relationship = %s',
                    ],
                    params=[
                        int(GroupLink.LinkedType.commit),
                        int(GroupLink.Relationship.resolves),
                    ]))
            commit_resolutions = {
                i.group_id: d
                for i, d in itertools.izip(commit_results,
                                           serialize(commit_results, user))
            }
        else:
            release_resolutions = {}
            commit_resolutions = {}

        actor_ids = set(r[-1] for r in six.itervalues(release_resolutions))
        actor_ids.update(r.actor_id for r in six.itervalues(ignore_items))
        if actor_ids:
            users = list(
                User.objects.filter(
                    id__in=actor_ids,
                    is_active=True,
                ))
            actors = {
                u.id: d
                for u, d in itertools.izip(users, serialize(users, user))
            }
        else:
            actors = {}

        share_ids = dict(
            GroupShare.objects.filter(group__in=item_list, ).values_list(
                'group_id', 'uuid'))

        result = {}
        for item in item_list:
            active_date = item.active_at or item.first_seen

            annotations = []
            for plugin in plugins.for_project(project=item.project, version=1):
                safe_execute(plugin.tags,
                             None,
                             item,
                             annotations,
                             _with_transaction=False)
            for plugin in plugins.for_project(project=item.project, version=2):
                annotations.extend(
                    safe_execute(plugin.get_annotations,
                                 group=item,
                                 _with_transaction=False) or ())

            from sentry.integrations import IntegrationFeatures
            for integration in Integration.objects.filter(
                    organizations=item.project.organization_id):
                if not (integration.has_feature(
                        IntegrationFeatures.ISSUE_BASIC)
                        or integration.has_feature(
                            IntegrationFeatures.ISSUE_SYNC)):
                    continue

                install = integration.get_installation(
                    item.project.organization_id)
                annotations.extend(
                    safe_execute(install.get_annotations,
                                 group=item,
                                 _with_transaction=False) or ())

            resolution_actor = None
            resolution_type = None
            resolution = release_resolutions.get(item.id)
            if resolution:
                resolution_type = 'release'
                resolution_actor = actors.get(resolution[-1])
            if not resolution:
                resolution = commit_resolutions.get(item.id)
                if resolution:
                    resolution_type = 'commit'

            ignore_item = ignore_items.get(item.id)
            if ignore_item:
                ignore_actor = actors.get(ignore_item.actor_id)
            else:
                ignore_actor = None

            result[item] = {
                'assigned_to': resolved_assignees.get(item.id),
                'is_bookmarked': item.id in bookmarks,
                'subscription': subscriptions[item.id],
                'has_seen':
                seen_groups.get(item.id, active_date) > active_date,
                'annotations': annotations,
                'user_count': user_counts.get(item.id, 0),
                'ignore_until': ignore_item,
                'ignore_actor': ignore_actor,
                'resolution': resolution,
                'resolution_type': resolution_type,
                'resolution_actor': resolution_actor,
                'share_id': share_ids.get(item.id),
                'times_seen': times_seen.get(item.id, 0),
                'first_seen': first_seen.get(item.id),  # TODO: missing?
                'last_seen': last_seen.get(item.id),
            }
        return result