mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
203 lines
6.4 KiB
Python
203 lines
6.4 KiB
Python
# Third party imports
|
|
from rest_framework import status
|
|
from rest_framework.response import Response
|
|
from sentry_sdk import capture_exception
|
|
|
|
# Module imports
|
|
from plane.app.views import BaseViewSet, BaseAPIView
|
|
from plane.db.models import (
|
|
GithubIssueSync,
|
|
GithubRepositorySync,
|
|
GithubRepository,
|
|
WorkspaceIntegration,
|
|
ProjectMember,
|
|
Label,
|
|
GithubCommentSync,
|
|
Project,
|
|
)
|
|
from plane.app.serializers import (
|
|
GithubIssueSyncSerializer,
|
|
GithubRepositorySyncSerializer,
|
|
GithubCommentSyncSerializer,
|
|
)
|
|
from plane.utils.integrations.github import get_github_repos
|
|
from plane.app.permissions import (
|
|
ProjectBasePermission,
|
|
ProjectEntityPermission,
|
|
)
|
|
|
|
|
|
class GithubRepositoriesEndpoint(BaseAPIView):
|
|
permission_classes = [
|
|
ProjectBasePermission,
|
|
]
|
|
|
|
def get(self, request, slug, workspace_integration_id):
|
|
page = request.GET.get("page", 1)
|
|
workspace_integration = WorkspaceIntegration.objects.get(
|
|
workspace__slug=slug, pk=workspace_integration_id
|
|
)
|
|
|
|
if workspace_integration.integration.provider != "github":
|
|
return Response(
|
|
{"error": "Not a github integration"},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
access_tokens_url = workspace_integration.metadata["access_tokens_url"]
|
|
repositories_url = (
|
|
workspace_integration.metadata["repositories_url"]
|
|
+ f"?per_page=100&page={page}"
|
|
)
|
|
repositories = get_github_repos(access_tokens_url, repositories_url)
|
|
return Response(repositories, status=status.HTTP_200_OK)
|
|
|
|
|
|
class GithubRepositorySyncViewSet(BaseViewSet):
|
|
permission_classes = [
|
|
ProjectBasePermission,
|
|
]
|
|
|
|
serializer_class = GithubRepositorySyncSerializer
|
|
model = GithubRepositorySync
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(project_id=self.kwargs.get("project_id"))
|
|
|
|
def get_queryset(self):
|
|
return (
|
|
super()
|
|
.get_queryset()
|
|
.filter(workspace__slug=self.kwargs.get("slug"))
|
|
.filter(project_id=self.kwargs.get("project_id"))
|
|
)
|
|
|
|
def create(self, request, slug, project_id, workspace_integration_id):
|
|
name = request.data.get("name", False)
|
|
url = request.data.get("url", False)
|
|
config = request.data.get("config", {})
|
|
repository_id = request.data.get("repository_id", False)
|
|
owner = request.data.get("owner", False)
|
|
|
|
if not name or not url or not repository_id or not owner:
|
|
return Response(
|
|
{"error": "Name, url, repository_id and owner are required"},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
# Get the workspace integration
|
|
workspace_integration = WorkspaceIntegration.objects.get(
|
|
pk=workspace_integration_id
|
|
)
|
|
|
|
# Delete the old repository object
|
|
GithubRepositorySync.objects.filter(
|
|
project_id=project_id, workspace__slug=slug
|
|
).delete()
|
|
GithubRepository.objects.filter(
|
|
project_id=project_id, workspace__slug=slug
|
|
).delete()
|
|
|
|
# Create repository
|
|
repo = GithubRepository.objects.create(
|
|
name=name,
|
|
url=url,
|
|
config=config,
|
|
repository_id=repository_id,
|
|
owner=owner,
|
|
project_id=project_id,
|
|
)
|
|
|
|
# Create a Label for github
|
|
label = Label.objects.filter(
|
|
name="GitHub",
|
|
project_id=project_id,
|
|
).first()
|
|
|
|
if label is None:
|
|
label = Label.objects.create(
|
|
name="GitHub",
|
|
project_id=project_id,
|
|
description="Label to sync Plane issues with GitHub issues",
|
|
color="#003773",
|
|
)
|
|
|
|
# Create repo sync
|
|
repo_sync = GithubRepositorySync.objects.create(
|
|
repository=repo,
|
|
workspace_integration=workspace_integration,
|
|
actor=workspace_integration.actor,
|
|
credentials=request.data.get("credentials", {}),
|
|
project_id=project_id,
|
|
label=label,
|
|
)
|
|
|
|
# Add bot as a member in the project
|
|
_ = ProjectMember.objects.get_or_create(
|
|
member=workspace_integration.actor, role=20, project_id=project_id
|
|
)
|
|
|
|
# Return Response
|
|
return Response(
|
|
GithubRepositorySyncSerializer(repo_sync).data,
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
|
|
|
|
class GithubIssueSyncViewSet(BaseViewSet):
|
|
permission_classes = [
|
|
ProjectEntityPermission,
|
|
]
|
|
|
|
serializer_class = GithubIssueSyncSerializer
|
|
model = GithubIssueSync
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(
|
|
project_id=self.kwargs.get("project_id"),
|
|
repository_sync_id=self.kwargs.get("repo_sync_id"),
|
|
)
|
|
|
|
|
|
class BulkCreateGithubIssueSyncEndpoint(BaseAPIView):
|
|
def post(self, request, slug, project_id, repo_sync_id):
|
|
project = Project.objects.get(pk=project_id, workspace__slug=slug)
|
|
|
|
github_issue_syncs = request.data.get("github_issue_syncs", [])
|
|
github_issue_syncs = GithubIssueSync.objects.bulk_create(
|
|
[
|
|
GithubIssueSync(
|
|
issue_id=github_issue_sync.get("issue"),
|
|
repo_issue_id=github_issue_sync.get("repo_issue_id"),
|
|
issue_url=github_issue_sync.get("issue_url"),
|
|
github_issue_id=github_issue_sync.get("github_issue_id"),
|
|
repository_sync_id=repo_sync_id,
|
|
project_id=project_id,
|
|
workspace_id=project.workspace_id,
|
|
created_by=request.user,
|
|
updated_by=request.user,
|
|
)
|
|
for github_issue_sync in github_issue_syncs
|
|
],
|
|
batch_size=100,
|
|
ignore_conflicts=True,
|
|
)
|
|
|
|
serializer = GithubIssueSyncSerializer(github_issue_syncs, many=True)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
class GithubCommentSyncViewSet(BaseViewSet):
|
|
permission_classes = [
|
|
ProjectEntityPermission,
|
|
]
|
|
|
|
serializer_class = GithubCommentSyncSerializer
|
|
model = GithubCommentSync
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(
|
|
project_id=self.kwargs.get("project_id"),
|
|
issue_sync_id=self.kwargs.get("issue_sync_id"),
|
|
)
|