def build_context(group: Group) -> Mapping[str, Any]: result, stats_24hr = get_serialized_and_stats(group, "24h") _, stats_14d = get_serialized_and_stats(group, "14d") first_release = group.get_first_release() if first_release is not None: last_release = group.get_last_release() else: last_release = None first_release_url = None if first_release: first_release_url = get_release_url(group, first_release) last_release_url = None if last_release: last_release_url = get_release_url(group, last_release) group_url = group.get_absolute_url( params={"referrer": "sentry-issues-glance"}) return { "type": result.get("metadata", {}).get("type", "Unknown Error"), "title": group.title, "title_url": group_url, "first_seen": result["firstSeen"], "last_seen": result["lastSeen"], "first_release": first_release, "first_release_url": first_release_url, "last_release": last_release, "last_release_url": last_release_url, "stats_24hr": stats_24hr, "stats_14d": stats_14d, }
def get_title_link( group: Group, event: Optional[Event], link_to_event: bool, issue_details: bool, notification: Optional[BaseNotification], ) -> Any: if event and link_to_event: return group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) if issue_details: referrer = re.sub("Notification$", "Slack", notification.__class__.__name__) return group.get_absolute_url(params={"referrer": referrer}) return group.get_absolute_url(params={"referrer": "slack"})
def new_note(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) note = Activity( group=event.group, event=event, project=event.project, type=Activity.NOTE, user=request.user, data={'text': 'This is an example note!'}, ) preview = MailPreview( html_template='sentry/emails/activity/note.html', text_template='sentry/emails/activity/note.txt', context={ 'data': note.data, 'author': note.user, 'date': note.datetime, 'group': group, 'link': group.get_absolute_url(), }, ) return render_to_response('sentry/debug/mail/preview.html', { 'preview': preview, })
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, project=event.project, type=Activity.ASSIGNED, user=request.user, data={ 'text': 'This is an example note!', 'assignee': '*****@*****.**' }, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
def get_title_link( group: Group, event: Optional[Event], link_to_event: bool, issue_details: bool, notification: Optional[BaseNotification], ) -> str: if event and link_to_event: url = group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) elif issue_details: referrer = re.sub("Notification$", "Slack", notification.__class__.__name__) url = group.get_absolute_url(params={"referrer": referrer}) else: url = group.get_absolute_url(params={"referrer": "slack"}) # Explicitly typing to satisfy mypy. url_str: str = url return url_str
def get_title_link( group: Group, event: Event | None, link_to_event: bool, issue_details: bool, notification: BaseNotification | None, ) -> str: if event and link_to_event: url = group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) elif issue_details and notification: referrer = notification.get_referrer(ExternalProviders.SLACK) url = group.get_absolute_url(params={"referrer": referrer}) else: url = group.get_absolute_url(params={"referrer": "slack"}) # Explicitly typing to satisfy mypy. url_str: str = url return url_str
def get_link_issue_config(self, group: Group, **kwargs: Any) -> Sequence[Mapping[str, Any]]: default_repo, repo_choices = self.get_repository_choices( group, **kwargs) org = group.organization autocomplete_url = reverse("sentry-extensions-github-search", args=[org.slug, self.model.id]) return [ { "name": "repo", "label": "GitHub Repository", "type": "select", "default": default_repo, "choices": repo_choices, "url": autocomplete_url, "required": True, "updatesForm": True, }, { "name": "externalIssue", "label": "Issue", "default": "", "choices": [], "type": "select", "url": autocomplete_url, "required": True, }, { "name": "comment", "label": "Comment", "default": "Sentry issue: [{issue_id}]({url})".format( url=absolute_uri( group.get_absolute_url( params={"referrer": "github_integration"})), issue_id=group.qualified_short_id, ), "type": "textarea", "required": False, "autosize": True, "help": "Leave blank if you don't want to add a comment to the GitHub issue.", }, ]
def assigned(request): org = Organization( id=1, slug='example', name='Example', ) team = Team( id=1, slug='example', name='Example', organization=org, ) project = Project( id=1, slug='example', name='Example', team=team, organization=org, ) group = Group( id=1, project=project, message='This is an example event.', ) event = Event( id=1, project=project, group=group, message=group.message, data=load_data('python'), ) assigned = Activity( group=event.group, event=event, project=event.project, type=Activity.ASSIGNED, user=request.user, data={'text': 'This is an example note!'}, ) return MailPreview( html_template='sentry/emails/activity/assigned.html', text_template='sentry/emails/activity/assigned.txt', context={ 'data': assigned.data, 'author': assigned.user, 'date': assigned.datetime, 'group': group, 'link': group.get_absolute_url(), }, ).render()
def get_group_settings_link( group: Group, environment: str | None, rule_details: Sequence[NotificationRuleDetails] | None = None, alert_timestamp: int | None = None, ) -> str: alert_type = str(AlertRuleTriggerAction.Type.EMAIL.name).lower() alert_timestamp_str = (str(round(time.time() * 1000)) if not alert_timestamp else str(alert_timestamp)) alert_rule_id = str( rule_details[0].id) if rule_details and rule_details[0].id else None query_params = {"referrer": "alert_email"} if environment: query_params["environment"] = environment if alert_type: query_params["alert_type"] = alert_type if alert_timestamp: query_params["alert_timestamp"] = alert_timestamp_str if alert_rule_id: query_params["alert_rule_id"] = alert_rule_id return str(group.get_absolute_url(params=query_params))
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, }
def get_link(group: Group, environment: Optional[str]) -> str: query_params = {"referrer": "alert_email"} if environment: query_params["environment"] = environment return str(group.get_absolute_url(params=query_params))
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, issue_alert: bool = False, ): # XXX(dcramer): options are limited to 100 choices, even when nested logo_url = absolute_uri( get_asset_url("sentry", "images/sentry-email-avatar.png")) text = build_attachment_text(group, event) or "" project = Project.objects.get_from_cache(id=group.project_id) # 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 = build_tag_fields(event_for_tags, tags) ts = group.last_seen if event: event_ts = event.datetime ts = max(ts, event_ts) footer = build_footer(group, issue_alert, project, rules) 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) elif issue_alert: title_link = group.get_absolute_url( params={"referrer": "IssueAlertSlack"}) else: title_link = group.get_absolute_url(params={"referrer": "slack"}) if not issue_alert: payload_actions, text, color = build_actions(group, project, text, color, actions, identity) else: payload_actions = [] 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, }