mirror of
https://github.com/jlengrand/bugsink.git
synced 2026-03-10 08:01:17 +00:00
SDK setup (WIP)
This commit is contained in:
@@ -145,6 +145,17 @@
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr class="bg-slate-50 border-slate-300 border-2 ">
|
||||
<td>
|
||||
</td>
|
||||
|
||||
<td class="w-full ml-0 pb-4 pt-4 pr-4 text-center">
|
||||
<div class="p-4">
|
||||
No issues found.
|
||||
This might mean you have not yet <a class="text-cyan-500 font-bold" href="{% url "project_sdk_setup" project_pk=project.id %}">set up your SDK</a>.
|
||||
</div>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.template.defaultfilters import yesno
|
||||
from django.urls import reverse
|
||||
|
||||
from teams.models import TeamMembership
|
||||
|
||||
@@ -58,19 +59,25 @@ class MyProjectMembershipForm(forms.ModelForm):
|
||||
|
||||
class ProjectForm(forms.ModelForm):
|
||||
|
||||
dsn = forms.CharField(label="DSN", disabled=True)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
team_qs = kwargs.pop("team_qs", None)
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.instance is not None and self.instance.pk is not None:
|
||||
if self.instance is None or self.instance.pk is None:
|
||||
# for editing, we disallow changing the team. consideration: it's somewhat hard to see what the consequences
|
||||
# for authorization are (from the user's perspective).
|
||||
del self.fields["team"]
|
||||
del self.fields["dsn"]
|
||||
|
||||
# if we ever push slug to the form, editing it should probably be disallowed as well (but mainly because it
|
||||
# has consequences on the issue's short identifier)
|
||||
# del self.fields["slug"]
|
||||
else:
|
||||
self.fields["team"].queryset = team_qs
|
||||
self.fields["dsn"].initial = self.instance.dsn
|
||||
self.fields["dsn"].label = "DSN (read-only)"
|
||||
self.fields["dsn"].help_text = 'Use the DSN to <a href="' + reverse('project_sdk_setup', kwargs={'project_pk': self.instance.pk}) + '" class="text-cyan-800 font-bold">set up the SDK</a>.'
|
||||
|
||||
class Meta:
|
||||
model = Project
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{% block title %}Edit {{ project.name }} · {{ site_title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{# div class="text-cyan-800" here in an attempt to trigger tailwind, which does not pick up Pyhton code #}
|
||||
|
||||
|
||||
<div class="flex items-center justify-center">
|
||||
@@ -50,6 +51,23 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if form.dsn %}
|
||||
<div class="text-lg mb-8">
|
||||
<div class="text-slate-800 font-bold">{{ form.dsn.label }}</div>
|
||||
<div class="flex items-center">
|
||||
{{ form.dsn }}
|
||||
|
||||
</div>
|
||||
{% if form.dsn.errors %}
|
||||
{% for error in form.dsn.errors %}
|
||||
<div class="text-red-500 pt-1 px-2 text-sm">{{ error }}</div>
|
||||
{% endfor %}
|
||||
{% elif form.dsn.help_text %}
|
||||
<div class="text-gray-500 pt-1 px-2 text-sm">{{ form.dsn.help_text|safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<button name="action" value="invite" class="font-bold text-slate-800 border-slate-500 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 hover:bg-cyan-400 active:ring rounded-md">Save</button>
|
||||
<a href="{% url "project_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
|
||||
</form>
|
||||
|
||||
@@ -93,6 +93,16 @@
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="pr-2">
|
||||
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer" onclick="followContainedLink(this);" >
|
||||
<a href="{% url 'project_sdk_setup' project_pk=project.id %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 9.75 16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0 0 20.25 18V6A2.25 2.25 0 0 0 18 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25Z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if project.member %}
|
||||
{% if not project.member.accepted %}
|
||||
|
||||
87
projects/templates/projects/project_sdk_setup.html
Normal file
87
projects/templates/projects/project_sdk_setup.html
Normal file
@@ -0,0 +1,87 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Set up your SDK · {{ site_title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="flex items-center justify-center">
|
||||
|
||||
<div class="m-4 max-w-4xl flex-auto">
|
||||
<h1 class="text-4xl font-bold">Set up your SDK</h1>
|
||||
|
||||
<div class="mt-4">
|
||||
To get started, you need to set up your SDK. Follow the instructions below to set up your SDK.
|
||||
</div>
|
||||
|
||||
<div class="mt-4 italic">
|
||||
Note: currently, we only support the Python SDK. Other SDKs might actually work, but have not been tested.
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
Bugsink is compatible with the Sentry SDK. A basic setup is the following:
|
||||
</div>
|
||||
|
||||
<h2 class="mt-8 text-2xl font-bold">Step 1: Install the SDK</h2>
|
||||
|
||||
<div class="mt-4">
|
||||
Install the SDK using pip:
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="p-4 mt-4 bg-slate-50 syntax-coloring"><pre><span>pip install sentry-sdk</span></pre></div>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-8 text-2xl font-bold">Step 2: Initialize the SDK</h2>
|
||||
|
||||
<div class="mt-4">
|
||||
Initialize the SDK with your DSN:
|
||||
</div>
|
||||
|
||||
{% comment %} add hoc construction of highlighted code:
|
||||
from pygments import highlight
|
||||
from pygments.lexers import PythonLexer
|
||||
from pygments.formatters import HtmlFormatter
|
||||
lexer = PythonLexer()
|
||||
code = """import sentry_sdk
|
||||
sentry_sdk.init(
|
||||
"foo",
|
||||
traces_sample_rate=0, # Bugsink intentionally does not support traces
|
||||
)"""
|
||||
print(highlight(code, lexer, HtmlFormatter()))
|
||||
{% endcomment %}
|
||||
|
||||
<div class="p-4 mt-4 bg-slate-50 syntax-coloring"><pre><span></span><span class="kn">import</span> <span class="nn">sentry_sdk</span>
|
||||
<span class="n">sentry_sdk</span><span class="o">.</span><span class="n">init</span><span class="p">(</span>
|
||||
<span class="s2">"{{ project.dsn }}"</span><span class="p">,</span>
|
||||
<span class="n">traces_sample_rate</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="c1"># Bugsink intentionally does not support traces</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
<div class="mt-4">
|
||||
For integration-specific (Django, Flask, etc) notes, see the <a href="https://docs.sentry.io/platforms/python/" class="text-cyan-500 font-bold" target="_blank">Sentry documentation</a>.
|
||||
</div>
|
||||
|
||||
<h2 class="mt-6 text-2xl font-bold">Step 3: Verify the setup</h2>
|
||||
|
||||
<div class="mt-4">
|
||||
Verify the setup by sending an event:
|
||||
</div>
|
||||
|
||||
<div class="p-4 mt-4 bg-slate-50 syntax-coloring"><pre><span></span><span class="kn">import</span> <span class="nn">sentry_sdk</span>
|
||||
<span class="n">division_by_zero</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">0</span>
|
||||
</pre></div>
|
||||
|
||||
<div class="mt-4">
|
||||
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 font-bold">list of open issues</a>.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -2,10 +2,11 @@ from django.urls import path
|
||||
|
||||
from .views import (
|
||||
project_list, project_members, project_members_accept, project_member_settings, project_members_invite,
|
||||
project_members_accept_new_user, project_new, project_edit)
|
||||
project_members_accept_new_user, project_new, project_edit, project_sdk_setup)
|
||||
|
||||
urlpatterns = [
|
||||
path('', project_list, name="project_list"),
|
||||
|
||||
path('mine/', project_list, kwargs={"ownership_filter": "mine"}, name="project_list_mine"),
|
||||
path('teams/', project_list, kwargs={"ownership_filter": "teams"}, name="project_list_teams"),
|
||||
path('other/', project_list, kwargs={"ownership_filter": "other"}, name="project_list_other"),
|
||||
@@ -17,4 +18,6 @@ urlpatterns = [
|
||||
path('<str:project_pk>/members/accept/<str:token>/', project_members_accept_new_user,
|
||||
name="project_members_accept_new_user"),
|
||||
path('<int:project_pk>/members/settings/<str:user_pk>/', project_member_settings, name="project_member_settings"),
|
||||
|
||||
path('<int:project_pk>/sdk-setup/', project_sdk_setup, name="project_sdk_setup"),
|
||||
]
|
||||
|
||||
@@ -124,7 +124,7 @@ def project_new(request):
|
||||
|
||||
# the user who creates the project is automatically an (accepted) admin of the project
|
||||
ProjectMembership.objects.create(project=project, user=request.user, role=ProjectRole.ADMIN, accepted=True)
|
||||
return redirect('project_members', project_pk=project.id)
|
||||
return redirect('project_sdk_setup', project_pk=project.id)
|
||||
|
||||
else:
|
||||
form = ProjectForm(team_qs=team_qs)
|
||||
@@ -363,3 +363,15 @@ def project_members_accept(request, project_pk):
|
||||
raise Http404("Invalid action")
|
||||
|
||||
return render(request, "projects/project_members_accept.html", {"project": project, "membership": membership})
|
||||
|
||||
|
||||
def project_sdk_setup(request, project_pk):
|
||||
project = Project.objects.get(id=project_pk)
|
||||
|
||||
if not request.user.is_superuser and not ProjectMembership.objects.filter(project=project, user=request.user,
|
||||
accepted=True).exists():
|
||||
raise PermissionDenied("You are not a member of this project")
|
||||
|
||||
return render(request, "projects/project_sdk_setup.html", {
|
||||
"project": project,
|
||||
})
|
||||
|
||||
2
theme/static/css/dist/styles.css
vendored
2
theme/static/css/dist/styles.css
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user