Пример #1
0
def build_actions(
    group: Group,
    project: Project,
    text: str,
    color: str,
    actions: Sequence[MessageAction] | None = None,
    identity: Identity | None = None,
) -> tuple[Sequence[MessageAction], str, str]:
    """Having actions means a button will be shown on the Slack message e.g. ignore, resolve, assign."""
    if actions:
        text += get_action_text(text, actions, identity)
        return [], text, "_actioned_issue"

    ignore_button = MessageAction(
        name="status",
        label="Ignore",
        value="ignored",
    )

    resolve_button = MessageAction(
        name="resolve_dialog",
        label="Resolve...",
        value="resolve_dialog",
    )

    status = group.get_status()

    if not has_releases(project):
        resolve_button = MessageAction(
            name="status",
            label="Resolve",
            value="resolved",
        )

    if status == GroupStatus.RESOLVED:
        resolve_button = MessageAction(
            name="status",
            label="Unresolve",
            value="unresolved",
        )

    if status == GroupStatus.IGNORED:
        ignore_button = MessageAction(
            name="status",
            label="Stop Ignoring",
            value="unresolved",
        )

    assignee = group.get_assignee()
    assign_button = MessageAction(
        name="assign",
        label="Select Assignee...",
        type="select",
        selected_options=format_actor_options([assignee]) if assignee else [],
        option_groups=get_option_groups(group),
    )

    return [resolve_button, ignore_button, assign_button], text, color
Пример #2
0
def build_actions(
    group: Group,
    project: Project,
    text: str,
    color: str,
    actions: Optional[Sequence[Any]] = None,
    identity: Optional[Identity] = None,
) -> Tuple[Sequence[Any], str, str]:
    """
    Having actions means a button will be shown on the Slack message e.g. ignore, resolve, assign
    """
    status = group.get_status()
    members = get_member_assignees(group)
    teams = get_team_assignees(group)

    if actions is None:
        actions = []

    assignee = get_assignee(group)

    resolve_button = {
        "name": "resolve_dialog",
        "value": "resolve_dialog",
        "type": "button",
        "text": "Resolve...",
    }

    ignore_button = {
        "name": "status",
        "value": "ignored",
        "type": "button",
        "text": "Ignore"
    }

    cache_key = "has_releases:2:%s" % project.id
    has_releases = cache.get(cache_key)
    if has_releases is None:
        has_releases = ReleaseProject.objects.filter(
            project_id=project.id).exists()
        if has_releases:
            cache.set(cache_key, True, 3600)
        else:
            cache.set(cache_key, False, 60)

    if not has_releases:
        resolve_button.update({
            "name": "status",
            "text": "Resolve",
            "value": "resolved"
        })

    if status == GroupStatus.RESOLVED:
        resolve_button.update({
            "name": "status",
            "text": "Unresolve",
            "value": "unresolved"
        })

    if status == GroupStatus.IGNORED:
        ignore_button.update({"text": "Stop Ignoring", "value": "unresolved"})

    option_groups = []

    if teams:
        option_groups.append({"text": "Teams", "options": teams})

    if members:
        option_groups.append({"text": "People", "options": members})

    payload_actions = [
        resolve_button,
        ignore_button,
        {
            "name": "assign",
            "text": "Select Assignee...",
            "type": "select",
            "selected_options": [assignee],
            "option_groups": option_groups,
        },
    ]

    if actions:
        action_texts = [
            _f
            for _f in [build_action_text(group, identity, a) for a in actions]
            if _f
        ]
        text += "\n" + "\n".join(action_texts)

        color = "_actioned_issue"
        payload_actions = []

    return payload_actions, text, color
Пример #3
0
def build_group_attachment(
    group: Group,
    event=None,
    tags: Mapping[str, str] = None,
    identity: Identity = None,
    actions=None,
    rules: List[Rule] = None,
    link_to_event: bool = False,
):
    # XXX(dcramer): options are limited to 100 choices, even when nested
    status = group.get_status()

    members = get_member_assignees(group)
    teams = get_team_assignees(group)

    logo_url = absolute_uri(get_asset_url("sentry", "images/sentry-email-avatar.png"))
    text = build_attachment_text(group, event) or ""

    if actions is None:
        actions = []

    assignee = get_assignee(group)

    resolve_button = {
        "name": "resolve_dialog",
        "value": "resolve_dialog",
        "type": "button",
        "text": "Resolve...",
    }

    ignore_button = {"name": "status", "value": "ignored", "type": "button", "text": "Ignore"}

    project = Project.objects.get_from_cache(id=group.project_id)

    cache_key = "has_releases:2:%s" % (project.id)
    has_releases = cache.get(cache_key)
    if has_releases is None:
        has_releases = ReleaseProject.objects.filter(project_id=project.id).exists()
        if has_releases:
            cache.set(cache_key, True, 3600)
        else:
            cache.set(cache_key, False, 60)

    if not has_releases:
        resolve_button.update({"name": "status", "text": "Resolve", "value": "resolved"})

    if status == GroupStatus.RESOLVED:
        resolve_button.update({"name": "status", "text": "Unresolve", "value": "unresolved"})

    if status == GroupStatus.IGNORED:
        ignore_button.update({"text": "Stop Ignoring", "value": "unresolved"})

    option_groups = []

    if teams:
        option_groups.append({"text": "Teams", "options": teams})

    if members:
        option_groups.append({"text": "People", "options": members})

    payload_actions = [
        resolve_button,
        ignore_button,
        {
            "name": "assign",
            "text": "Select Assignee...",
            "type": "select",
            "selected_options": [assignee],
            "option_groups": option_groups,
        },
    ]

    # If an event is unspecified, use the tags of the latest event (if one exists).
    event_for_tags = event if event else group.get_latest_event()

    fallback_color = LEVEL_TO_COLOR["error"]
    color = (
        LEVEL_TO_COLOR.get(event_for_tags.get_tag("level"), fallback_color)
        if event_for_tags
        else fallback_color
    )

    fields = []
    if tags:
        event_tags = event_for_tags.tags if event_for_tags else []
        for key, value in event_tags:
            std_key = tagstore.get_standardized_key(key)
            if std_key not in tags:
                continue

            labeled_value = tagstore.get_tag_value_label(key, value)
            fields.append(
                {
                    "title": std_key.encode("utf-8"),
                    "value": labeled_value.encode("utf-8"),
                    "short": True,
                }
            )

    if actions:
        action_texts = [_f for _f in [build_action_text(group, identity, a) for a in actions] if _f]
        text += "\n" + "\n".join(action_texts)

        color = ACTIONED_ISSUE_COLOR
        payload_actions = []

    ts = group.last_seen

    if event:
        event_ts = event.datetime
        ts = max(ts, event_ts)

    footer = f"{group.qualified_short_id}"

    if rules:
        rule_url = build_rule_url(rules[0], group, project)
        footer += f" via <{rule_url}|{rules[0].label}>"

        if len(rules) > 1:
            footer += f" (+{len(rules) - 1} other)"

    obj = event if event is not None else group
    if event and link_to_event:
        title_link = group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id)
    else:
        title_link = group.get_absolute_url(params={"referrer": "slack"})

    return {
        "fallback": f"[{project.slug}] {obj.title}",
        "title": build_attachment_title(obj),
        "title_link": title_link,
        "text": text,
        "fields": fields,
        "mrkdwn_in": ["text"],
        "callback_id": json.dumps({"issue": group.id}),
        "footer_icon": logo_url,
        "footer": footer,
        "ts": to_timestamp(ts),
        "color": color,
        "actions": payload_actions,
    }