-
Notifications
You must be signed in to change notification settings - Fork 429
/
Copy pathviews.py
110 lines (94 loc) · 4.15 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import re
from django.shortcuts import get_object_or_404
from rest_framework import status, viewsets
from rest_framework.response import Response
from features.models import Feature
from features.permissions import FeatureExternalResourcePermissions
from integrations.github.client import (
get_github_issue_pr_title_and_state,
label_github_issue_pr,
)
from integrations.github.models import GithubRepository
from organisations.models import Organisation
from .models import FeatureExternalResource
from .serializers import FeatureExternalResourceSerializer
class FeatureExternalResourceViewSet(viewsets.ModelViewSet):
serializer_class = FeatureExternalResourceSerializer
permission_classes = [FeatureExternalResourcePermissions]
def get_queryset(self):
if "pk" in self.kwargs:
return FeatureExternalResource.objects.filter(id=self.kwargs["pk"])
else:
features_pk = self.kwargs["feature_pk"]
return FeatureExternalResource.objects.filter(feature=features_pk)
# Override get list view to add github issue/pr name to each linked external resource
def list(self, request, *args, **kwargs) -> Response:
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
# get organisation id from feature and get feature from validated data
organisation_id = get_object_or_404(
Feature.objects.filter(id=self.kwargs["feature_pk"]),
).project.organisation_id
for resource in data if isinstance(data, list) else []:
if resource_url := resource.get("url"):
resource["metadata"] = get_github_issue_pr_title_and_state(
organisation_id=organisation_id, resource_url=resource_url
)
return Response(data={"results": data})
def create(self, request, *args, **kwargs):
feature = get_object_or_404(
Feature.objects.filter(
id=self.kwargs["feature_pk"],
),
)
github_configuration = (
Organisation.objects.prefetch_related("github_config")
.get(id=feature.project.organisation_id)
.github_config.first()
)
if not github_configuration or not hasattr(feature.project, "github_project"):
return Response(
data={
"detail": "This Project doesn't have a valid GitHub integration configuration"
},
content_type="application/json",
status=status.HTTP_400_BAD_REQUEST,
)
# Get repository owner and name, and issue/PR number from the external resource URL
url = request.data.get("url")
if request.data.get("type") == "GITHUB_PR":
pattern = r"github.com/([^/]+)/([^/]+)/pull/(\d+)$"
elif request.data.get("type") == "GITHUB_ISSUE":
pattern = r"github.com/([^/]+)/([^/]+)/issues/(\d+)$"
else:
return Response(
data={"detail": "Incorrect GitHub type"},
content_type="application/json",
status=status.HTTP_400_BAD_REQUEST,
)
url_match = re.search(pattern, url)
if url_match:
owner, repo, issue = url_match.groups()
if GithubRepository.objects.get(
github_configuration=github_configuration,
repository_owner=owner,
repository_name=repo,
).tagging_enabled:
label_github_issue_pr(
installation_id=github_configuration.installation_id,
owner=owner,
repo=repo,
issue=issue,
)
response = super().create(request, *args, **kwargs)
return response
else:
return Response(
data={"detail": "Invalid GitHub Issue/PR URL"},
content_type="application/json",
status=status.HTTP_400_BAD_REQUEST,
)
def perform_update(self, serializer):
external_resource_id = int(self.kwargs["pk"])
serializer.save(id=external_resource_id)