forked from github/plane
Merge branch 'develop' of https://github.com/makeplane/plane into feat/custom_attributes
This commit is contained in:
commit
d04eac30b0
@ -1,6 +1,7 @@
|
|||||||
# Backend
|
# Backend
|
||||||
# Debug value for api server use it as 0 for production use
|
# Debug value for api server use it as 0 for production use
|
||||||
DEBUG=0
|
DEBUG=0
|
||||||
|
DJANGO_SETTINGS_MODULE="plane.settings.selfhosted"
|
||||||
|
|
||||||
# Error logs
|
# Error logs
|
||||||
SENTRY_DSN=""
|
SENTRY_DSN=""
|
||||||
|
@ -23,7 +23,7 @@ from .project import (
|
|||||||
ProjectPublicMemberSerializer
|
ProjectPublicMemberSerializer
|
||||||
)
|
)
|
||||||
from .state import StateSerializer, StateLiteSerializer
|
from .state import StateSerializer, StateLiteSerializer
|
||||||
from .view import IssueViewSerializer, IssueViewFavoriteSerializer
|
from .view import GlobalViewSerializer, IssueViewSerializer, IssueViewFavoriteSerializer
|
||||||
from .cycle import CycleSerializer, CycleIssueSerializer, CycleFavoriteSerializer, CycleWriteSerializer
|
from .cycle import CycleSerializer, CycleIssueSerializer, CycleFavoriteSerializer, CycleWriteSerializer
|
||||||
from .asset import FileAssetSerializer
|
from .asset import FileAssetSerializer
|
||||||
from .issue import (
|
from .issue import (
|
||||||
|
@ -5,10 +5,39 @@ from rest_framework import serializers
|
|||||||
from .base import BaseSerializer
|
from .base import BaseSerializer
|
||||||
from .workspace import WorkspaceLiteSerializer
|
from .workspace import WorkspaceLiteSerializer
|
||||||
from .project import ProjectLiteSerializer
|
from .project import ProjectLiteSerializer
|
||||||
from plane.db.models import IssueView, IssueViewFavorite
|
from plane.db.models import GlobalView, IssueView, IssueViewFavorite
|
||||||
from plane.utils.issue_filters import issue_filters
|
from plane.utils.issue_filters import issue_filters
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalViewSerializer(BaseSerializer):
|
||||||
|
workspace_detail = WorkspaceLiteSerializer(source="workspace", read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = GlobalView
|
||||||
|
fields = "__all__"
|
||||||
|
read_only_fields = [
|
||||||
|
"workspace",
|
||||||
|
"query",
|
||||||
|
]
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
query_params = validated_data.get("query_data", {})
|
||||||
|
if bool(query_params):
|
||||||
|
validated_data["query"] = issue_filters(query_params, "POST")
|
||||||
|
else:
|
||||||
|
validated_data["query"] = dict()
|
||||||
|
return GlobalView.objects.create(**validated_data)
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
query_params = validated_data.get("query_data", {})
|
||||||
|
if bool(query_params):
|
||||||
|
validated_data["query"] = issue_filters(query_params, "POST")
|
||||||
|
else:
|
||||||
|
validated_data["query"] = dict()
|
||||||
|
validated_data["query"] = issue_filters(query_params, "PATCH")
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
|
||||||
class IssueViewSerializer(BaseSerializer):
|
class IssueViewSerializer(BaseSerializer):
|
||||||
is_favorite = serializers.BooleanField(read_only=True)
|
is_favorite = serializers.BooleanField(read_only=True)
|
||||||
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
project_detail = ProjectLiteSerializer(source="project", read_only=True)
|
||||||
|
@ -102,6 +102,8 @@ from plane.api.views import (
|
|||||||
BulkEstimatePointEndpoint,
|
BulkEstimatePointEndpoint,
|
||||||
## End Estimates
|
## End Estimates
|
||||||
# Views
|
# Views
|
||||||
|
GlobalViewViewSet,
|
||||||
|
GlobalViewIssuesViewSet,
|
||||||
IssueViewViewSet,
|
IssueViewViewSet,
|
||||||
ViewIssuesEndpoint,
|
ViewIssuesEndpoint,
|
||||||
IssueViewFavoriteViewSet,
|
IssueViewFavoriteViewSet,
|
||||||
@ -184,7 +186,6 @@ from plane.api.views import (
|
|||||||
## Exporter
|
## Exporter
|
||||||
ExportIssuesEndpoint,
|
ExportIssuesEndpoint,
|
||||||
## End Exporter
|
## End Exporter
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -241,7 +242,11 @@ urlpatterns = [
|
|||||||
UpdateUserTourCompletedEndpoint.as_view(),
|
UpdateUserTourCompletedEndpoint.as_view(),
|
||||||
name="user-tour",
|
name="user-tour",
|
||||||
),
|
),
|
||||||
path("users/workspaces/<str:slug>/activities/", UserActivityEndpoint.as_view(), name="user-activities"),
|
path(
|
||||||
|
"users/workspaces/<str:slug>/activities/",
|
||||||
|
UserActivityEndpoint.as_view(),
|
||||||
|
name="user-activities",
|
||||||
|
),
|
||||||
# user workspaces
|
# user workspaces
|
||||||
path(
|
path(
|
||||||
"users/me/workspaces/",
|
"users/me/workspaces/",
|
||||||
@ -649,6 +654,37 @@ urlpatterns = [
|
|||||||
ViewIssuesEndpoint.as_view(),
|
ViewIssuesEndpoint.as_view(),
|
||||||
name="project-view-issues",
|
name="project-view-issues",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"workspaces/<str:slug>/views/",
|
||||||
|
GlobalViewViewSet.as_view(
|
||||||
|
{
|
||||||
|
"get": "list",
|
||||||
|
"post": "create",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
name="global-view",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"workspaces/<str:slug>/views/<uuid:pk>/",
|
||||||
|
GlobalViewViewSet.as_view(
|
||||||
|
{
|
||||||
|
"get": "retrieve",
|
||||||
|
"put": "update",
|
||||||
|
"patch": "partial_update",
|
||||||
|
"delete": "destroy",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
name="global-view",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"workspaces/<str:slug>/issues/",
|
||||||
|
GlobalViewIssuesViewSet.as_view(
|
||||||
|
{
|
||||||
|
"get": "list",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
name="global-view-issues",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"workspaces/<str:slug>/projects/<uuid:project_id>/user-favorite-views/",
|
"workspaces/<str:slug>/projects/<uuid:project_id>/user-favorite-views/",
|
||||||
IssueViewFavoriteViewSet.as_view(
|
IssueViewFavoriteViewSet.as_view(
|
||||||
@ -767,11 +803,6 @@ urlpatterns = [
|
|||||||
),
|
),
|
||||||
name="project-issue",
|
name="project-issue",
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"workspaces/<str:slug>/issues/",
|
|
||||||
WorkSpaceIssuesEndpoint.as_view(),
|
|
||||||
name="workspace-issue",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"workspaces/<str:slug>/projects/<uuid:project_id>/issue-labels/",
|
"workspaces/<str:slug>/projects/<uuid:project_id>/issue-labels/",
|
||||||
LabelViewSet.as_view(
|
LabelViewSet.as_view(
|
||||||
|
@ -56,7 +56,7 @@ from .workspace import (
|
|||||||
LeaveWorkspaceEndpoint,
|
LeaveWorkspaceEndpoint,
|
||||||
)
|
)
|
||||||
from .state import StateViewSet
|
from .state import StateViewSet
|
||||||
from .view import IssueViewViewSet, ViewIssuesEndpoint, IssueViewFavoriteViewSet
|
from .view import GlobalViewViewSet, GlobalViewIssuesViewSet, IssueViewViewSet, ViewIssuesEndpoint, IssueViewFavoriteViewSet
|
||||||
from .cycle import (
|
from .cycle import (
|
||||||
CycleViewSet,
|
CycleViewSet,
|
||||||
CycleIssueViewSet,
|
CycleIssueViewSet,
|
||||||
|
@ -80,6 +80,7 @@ class CycleViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("pk", None)),
|
issue_id=str(self.kwargs.get("pk", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
@ -487,6 +488,7 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("pk", None)),
|
issue_id=str(self.kwargs.get("pk", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -662,6 +664,7 @@ class CycleIssueViewSet(BaseViewSet):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
# Return all Cycle Issues
|
# Return all Cycle Issues
|
||||||
|
@ -213,6 +213,7 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue.id),
|
issue_id=str(issue.id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
# create an inbox issue
|
# create an inbox issue
|
||||||
InboxIssue.objects.create(
|
InboxIssue.objects.create(
|
||||||
@ -277,6 +278,7 @@ class InboxIssueViewSet(BaseViewSet):
|
|||||||
IssueSerializer(current_instance).data,
|
IssueSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
issue_serializer.save()
|
issue_serializer.save()
|
||||||
else:
|
else:
|
||||||
@ -518,6 +520,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue.id),
|
issue_id=str(issue.id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
# create an inbox issue
|
# create an inbox issue
|
||||||
InboxIssue.objects.create(
|
InboxIssue.objects.create(
|
||||||
@ -582,6 +585,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
|
|||||||
IssueSerializer(current_instance).data,
|
IssueSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
issue_serializer.save()
|
issue_serializer.save()
|
||||||
return Response(issue_serializer.data, status=status.HTTP_200_OK)
|
return Response(issue_serializer.data, status=status.HTTP_200_OK)
|
||||||
|
@ -4,6 +4,7 @@ import random
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
# Django imports
|
# Django imports
|
||||||
|
from django.utils import timezone
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Prefetch,
|
Prefetch,
|
||||||
OuterRef,
|
OuterRef,
|
||||||
@ -129,6 +130,7 @@ class IssueViewSet(BaseViewSet):
|
|||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_update(serializer)
|
return super().perform_update(serializer)
|
||||||
@ -149,6 +151,7 @@ class IssueViewSet(BaseViewSet):
|
|||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -315,6 +318,7 @@ class IssueViewSet(BaseViewSet):
|
|||||||
issue_id=str(serializer.data.get("id", None)),
|
issue_id=str(serializer.data.get("id", None)),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -568,6 +572,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id")),
|
issue_id=str(self.kwargs.get("issue_id")),
|
||||||
project_id=str(self.kwargs.get("project_id")),
|
project_id=str(self.kwargs.get("project_id")),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
def perform_update(self, serializer):
|
def perform_update(self, serializer):
|
||||||
@ -586,6 +591,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
IssueCommentSerializer(current_instance).data,
|
IssueCommentSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_update(serializer)
|
return super().perform_update(serializer)
|
||||||
@ -607,6 +613,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||||||
IssueCommentSerializer(current_instance).data,
|
IssueCommentSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -890,6 +897,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id")),
|
issue_id=str(self.kwargs.get("issue_id")),
|
||||||
project_id=str(self.kwargs.get("project_id")),
|
project_id=str(self.kwargs.get("project_id")),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
def perform_update(self, serializer):
|
def perform_update(self, serializer):
|
||||||
@ -908,6 +916,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||||||
IssueLinkSerializer(current_instance).data,
|
IssueLinkSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_update(serializer)
|
return super().perform_update(serializer)
|
||||||
@ -929,6 +938,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||||||
IssueLinkSerializer(current_instance).data,
|
IssueLinkSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -1007,6 +1017,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||||||
serializer.data,
|
serializer.data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -1029,6 +1040,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -1231,6 +1243,7 @@ class IssueArchiveViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue.id),
|
issue_id=str(issue.id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(IssueSerializer(issue).data, status=status.HTTP_200_OK)
|
return Response(IssueSerializer(issue).data, status=status.HTTP_200_OK)
|
||||||
@ -1435,6 +1448,7 @@ class IssueReactionViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
def destroy(self, request, slug, project_id, issue_id, reaction_code):
|
def destroy(self, request, slug, project_id, issue_id, reaction_code):
|
||||||
@ -1458,6 +1472,7 @@ class IssueReactionViewSet(BaseViewSet):
|
|||||||
"identifier": str(issue_reaction.id),
|
"identifier": str(issue_reaction.id),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
issue_reaction.delete()
|
issue_reaction.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -1506,6 +1521,7 @@ class CommentReactionViewSet(BaseViewSet):
|
|||||||
issue_id=None,
|
issue_id=None,
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
def destroy(self, request, slug, project_id, comment_id, reaction_code):
|
def destroy(self, request, slug, project_id, comment_id, reaction_code):
|
||||||
@ -1530,6 +1546,7 @@ class CommentReactionViewSet(BaseViewSet):
|
|||||||
"comment_id": str(comment_id),
|
"comment_id": str(comment_id),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
comment_reaction.delete()
|
comment_reaction.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -1626,6 +1643,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue_id),
|
issue_id=str(issue_id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
if not ProjectMember.objects.filter(
|
if not ProjectMember.objects.filter(
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
@ -1675,6 +1693,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
IssueCommentSerializer(comment).data,
|
IssueCommentSerializer(comment).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -1708,6 +1727,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
|
|||||||
IssueCommentSerializer(comment).data,
|
IssueCommentSerializer(comment).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
comment.delete()
|
comment.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -1782,6 +1802,7 @@ class IssueReactionPublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -1826,6 +1847,7 @@ class IssueReactionPublicViewSet(BaseViewSet):
|
|||||||
"identifier": str(issue_reaction.id),
|
"identifier": str(issue_reaction.id),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
issue_reaction.delete()
|
issue_reaction.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -1899,6 +1921,7 @@ class CommentReactionPublicViewSet(BaseViewSet):
|
|||||||
issue_id=None,
|
issue_id=None,
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -1950,6 +1973,7 @@ class CommentReactionPublicViewSet(BaseViewSet):
|
|||||||
"comment_id": str(comment_id),
|
"comment_id": str(comment_id),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
comment_reaction.delete()
|
comment_reaction.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -2013,6 +2037,7 @@ class IssueVotePublicViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("issue_id", None)),
|
issue_id=str(self.kwargs.get("issue_id", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
serializer = IssueVoteSerializer(issue_vote)
|
serializer = IssueVoteSerializer(issue_vote)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
@ -2047,6 +2072,7 @@ class IssueVotePublicViewSet(BaseViewSet):
|
|||||||
"identifier": str(issue_vote.id),
|
"identifier": str(issue_vote.id),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
issue_vote.delete()
|
issue_vote.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -2080,6 +2106,7 @@ class IssueRelationViewSet(BaseViewSet):
|
|||||||
IssueRelationSerializer(current_instance).data,
|
IssueRelationSerializer(current_instance).data,
|
||||||
cls=DjangoJSONEncoder,
|
cls=DjangoJSONEncoder,
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -2113,6 +2140,7 @@ class IssueRelationViewSet(BaseViewSet):
|
|||||||
issue_id=str(issue_id),
|
issue_id=str(issue_id),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
if relation == "blocking":
|
if relation == "blocking":
|
||||||
@ -2157,6 +2185,8 @@ class IssueRelationViewSet(BaseViewSet):
|
|||||||
.select_related("issue")
|
.select_related("issue")
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class IssueRetrievePublicEndpoint(BaseAPIView):
|
class IssueRetrievePublicEndpoint(BaseAPIView):
|
||||||
permission_classes = [
|
permission_classes = [
|
||||||
AllowAny,
|
AllowAny,
|
||||||
@ -2382,6 +2412,7 @@ class IssueDraftViewSet(BaseViewSet):
|
|||||||
current_instance=json.dumps(
|
current_instance=json.dumps(
|
||||||
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
IssueSerializer(current_instance).data, cls=DjangoJSONEncoder
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_update(serializer)
|
return super().perform_update(serializer)
|
||||||
@ -2566,6 +2597,7 @@ class IssueDraftViewSet(BaseViewSet):
|
|||||||
issue_id=str(serializer.data.get("id", None)),
|
issue_id=str(serializer.data.get("id", None)),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
# Django Imports
|
# Django Imports
|
||||||
|
from django.utils import timezone
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import Prefetch, F, OuterRef, Func, Exists, Count, Q
|
from django.db.models import Prefetch, F, OuterRef, Func, Exists, Count, Q
|
||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
@ -129,6 +130,7 @@ class ModuleViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("pk", None)),
|
issue_id=str(self.kwargs.get("pk", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
@ -277,6 +279,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||||||
issue_id=str(self.kwargs.get("pk", None)),
|
issue_id=str(self.kwargs.get("pk", None)),
|
||||||
project_id=str(self.kwargs.get("project_id", None)),
|
project_id=str(self.kwargs.get("project_id", None)),
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
return super().perform_destroy(instance)
|
return super().perform_destroy(instance)
|
||||||
|
|
||||||
@ -444,6 +447,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
|
@ -1,4 +1,18 @@
|
|||||||
# Django imports
|
# Django imports
|
||||||
|
from django.db.models import (
|
||||||
|
Prefetch,
|
||||||
|
OuterRef,
|
||||||
|
Func,
|
||||||
|
F,
|
||||||
|
Case,
|
||||||
|
Value,
|
||||||
|
CharField,
|
||||||
|
When,
|
||||||
|
Exists,
|
||||||
|
Max,
|
||||||
|
)
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.decorators.gzip import gzip_page
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db.models import Prefetch, OuterRef, Exists
|
from django.db.models import Prefetch, OuterRef, Exists
|
||||||
|
|
||||||
@ -10,18 +24,192 @@ from sentry_sdk import capture_exception
|
|||||||
# Module imports
|
# Module imports
|
||||||
from . import BaseViewSet, BaseAPIView
|
from . import BaseViewSet, BaseAPIView
|
||||||
from plane.api.serializers import (
|
from plane.api.serializers import (
|
||||||
|
GlobalViewSerializer,
|
||||||
IssueViewSerializer,
|
IssueViewSerializer,
|
||||||
IssueLiteSerializer,
|
IssueLiteSerializer,
|
||||||
IssueViewFavoriteSerializer,
|
IssueViewFavoriteSerializer,
|
||||||
)
|
)
|
||||||
from plane.api.permissions import ProjectEntityPermission
|
from plane.api.permissions import WorkspaceEntityPermission, ProjectEntityPermission
|
||||||
from plane.db.models import (
|
from plane.db.models import (
|
||||||
|
Workspace,
|
||||||
|
GlobalView,
|
||||||
IssueView,
|
IssueView,
|
||||||
Issue,
|
Issue,
|
||||||
IssueViewFavorite,
|
IssueViewFavorite,
|
||||||
IssueReaction,
|
IssueReaction,
|
||||||
|
IssueLink,
|
||||||
|
IssueAttachment,
|
||||||
)
|
)
|
||||||
from plane.utils.issue_filters import issue_filters
|
from plane.utils.issue_filters import issue_filters
|
||||||
|
from plane.utils.grouper import group_results
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalViewViewSet(BaseViewSet):
|
||||||
|
serializer_class = GlobalViewSerializer
|
||||||
|
model = GlobalView
|
||||||
|
permission_classes = [
|
||||||
|
WorkspaceEntityPermission,
|
||||||
|
]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
workspace = Workspace.objects.get(slug=self.kwargs.get("slug"))
|
||||||
|
serializer.save(workspace_id=workspace.id)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return self.filter_queryset(
|
||||||
|
super()
|
||||||
|
.get_queryset()
|
||||||
|
.filter(workspace__slug=self.kwargs.get("slug"))
|
||||||
|
.select_related("workspace")
|
||||||
|
.order_by("-created_at")
|
||||||
|
.distinct()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalViewIssuesViewSet(BaseViewSet):
|
||||||
|
permission_classes = [
|
||||||
|
WorkspaceEntityPermission,
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return (
|
||||||
|
Issue.issue_objects.annotate(
|
||||||
|
sub_issues_count=Issue.issue_objects.filter(parent=OuterRef("id"))
|
||||||
|
.order_by()
|
||||||
|
.annotate(count=Func(F("id"), function="Count"))
|
||||||
|
.values("count")
|
||||||
|
)
|
||||||
|
.filter(workspace__slug=self.kwargs.get("slug"))
|
||||||
|
.select_related("project")
|
||||||
|
.select_related("workspace")
|
||||||
|
.select_related("state")
|
||||||
|
.select_related("parent")
|
||||||
|
.prefetch_related("assignees")
|
||||||
|
.prefetch_related("labels")
|
||||||
|
.prefetch_related(
|
||||||
|
Prefetch(
|
||||||
|
"issue_reactions",
|
||||||
|
queryset=IssueReaction.objects.select_related("actor"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(gzip_page)
|
||||||
|
def list(self, request, slug):
|
||||||
|
try:
|
||||||
|
filters = issue_filters(request.query_params, "GET")
|
||||||
|
|
||||||
|
# Custom ordering for priority and state
|
||||||
|
priority_order = ["urgent", "high", "medium", "low", "none"]
|
||||||
|
state_order = ["backlog", "unstarted", "started", "completed", "cancelled"]
|
||||||
|
|
||||||
|
order_by_param = request.GET.get("order_by", "-created_at")
|
||||||
|
|
||||||
|
issue_queryset = (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(**filters)
|
||||||
|
.filter(project__project_projectmember__member=self.request.user)
|
||||||
|
.annotate(cycle_id=F("issue_cycle__cycle_id"))
|
||||||
|
.annotate(module_id=F("issue_module__module_id"))
|
||||||
|
.annotate(
|
||||||
|
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
|
||||||
|
.order_by()
|
||||||
|
.annotate(count=Func(F("id"), function="Count"))
|
||||||
|
.values("count")
|
||||||
|
)
|
||||||
|
.annotate(
|
||||||
|
attachment_count=IssueAttachment.objects.filter(
|
||||||
|
issue=OuterRef("id")
|
||||||
|
)
|
||||||
|
.order_by()
|
||||||
|
.annotate(count=Func(F("id"), function="Count"))
|
||||||
|
.values("count")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Priority Ordering
|
||||||
|
if order_by_param == "priority" or order_by_param == "-priority":
|
||||||
|
priority_order = (
|
||||||
|
priority_order
|
||||||
|
if order_by_param == "priority"
|
||||||
|
else priority_order[::-1]
|
||||||
|
)
|
||||||
|
issue_queryset = issue_queryset.annotate(
|
||||||
|
priority_order=Case(
|
||||||
|
*[
|
||||||
|
When(priority=p, then=Value(i))
|
||||||
|
for i, p in enumerate(priority_order)
|
||||||
|
],
|
||||||
|
output_field=CharField(),
|
||||||
|
)
|
||||||
|
).order_by("priority_order")
|
||||||
|
|
||||||
|
# State Ordering
|
||||||
|
elif order_by_param in [
|
||||||
|
"state__name",
|
||||||
|
"state__group",
|
||||||
|
"-state__name",
|
||||||
|
"-state__group",
|
||||||
|
]:
|
||||||
|
state_order = (
|
||||||
|
state_order
|
||||||
|
if order_by_param in ["state__name", "state__group"]
|
||||||
|
else state_order[::-1]
|
||||||
|
)
|
||||||
|
issue_queryset = issue_queryset.annotate(
|
||||||
|
state_order=Case(
|
||||||
|
*[
|
||||||
|
When(state__group=state_group, then=Value(i))
|
||||||
|
for i, state_group in enumerate(state_order)
|
||||||
|
],
|
||||||
|
default=Value(len(state_order)),
|
||||||
|
output_field=CharField(),
|
||||||
|
)
|
||||||
|
).order_by("state_order")
|
||||||
|
# assignee and label ordering
|
||||||
|
elif order_by_param in [
|
||||||
|
"labels__name",
|
||||||
|
"-labels__name",
|
||||||
|
"assignees__first_name",
|
||||||
|
"-assignees__first_name",
|
||||||
|
]:
|
||||||
|
issue_queryset = issue_queryset.annotate(
|
||||||
|
max_values=Max(
|
||||||
|
order_by_param[1::]
|
||||||
|
if order_by_param.startswith("-")
|
||||||
|
else order_by_param
|
||||||
|
)
|
||||||
|
).order_by(
|
||||||
|
"-max_values" if order_by_param.startswith("-") else "max_values"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
issue_queryset = issue_queryset.order_by(order_by_param)
|
||||||
|
|
||||||
|
issues = IssueLiteSerializer(issue_queryset, many=True).data
|
||||||
|
|
||||||
|
## Grouping the results
|
||||||
|
group_by = request.GET.get("group_by", False)
|
||||||
|
sub_group_by = request.GET.get("sub_group_by", False)
|
||||||
|
if sub_group_by and sub_group_by == group_by:
|
||||||
|
return Response(
|
||||||
|
{"error": "Group by and sub group by cannot be same"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
if group_by:
|
||||||
|
return Response(
|
||||||
|
group_results(issues, group_by, sub_group_by), status=status.HTTP_200_OK
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(issues, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
capture_exception(e)
|
||||||
|
return Response(
|
||||||
|
{"error": "Something went wrong please try again later"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IssueViewViewSet(BaseViewSet):
|
class IssueViewViewSet(BaseViewSet):
|
||||||
|
@ -39,6 +39,7 @@ def track_name(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("name") != requested_data.get("name"):
|
if current_instance.get("name") != requested_data.get("name"):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
@ -52,6 +53,7 @@ def track_name(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the name to {requested_data.get('name')}",
|
comment=f"updated the name to {requested_data.get('name')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -64,6 +66,7 @@ def track_parent(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("parent") != requested_data.get("parent"):
|
if current_instance.get("parent") != requested_data.get("parent"):
|
||||||
if requested_data.get("parent") == None:
|
if requested_data.get("parent") == None:
|
||||||
@ -81,6 +84,7 @@ def track_parent(
|
|||||||
comment=f"updated the parent issue to None",
|
comment=f"updated the parent issue to None",
|
||||||
old_identifier=old_parent.id,
|
old_identifier=old_parent.id,
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -101,6 +105,7 @@ def track_parent(
|
|||||||
comment=f"updated the parent issue to {new_parent.name}",
|
comment=f"updated the parent issue to {new_parent.name}",
|
||||||
old_identifier=old_parent.id if old_parent is not None else None,
|
old_identifier=old_parent.id if old_parent is not None else None,
|
||||||
new_identifier=new_parent.id,
|
new_identifier=new_parent.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -113,6 +118,7 @@ def track_priority(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("priority") != requested_data.get("priority"):
|
if current_instance.get("priority") != requested_data.get("priority"):
|
||||||
if requested_data.get("priority") == None:
|
if requested_data.get("priority") == None:
|
||||||
@ -127,6 +133,7 @@ def track_priority(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the priority to None",
|
comment=f"updated the priority to None",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -141,6 +148,7 @@ def track_priority(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the priority to {requested_data.get('priority')}",
|
comment=f"updated the priority to {requested_data.get('priority')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -153,6 +161,7 @@ def track_state(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("state") != requested_data.get("state"):
|
if current_instance.get("state") != requested_data.get("state"):
|
||||||
new_state = State.objects.get(pk=requested_data.get("state", None))
|
new_state = State.objects.get(pk=requested_data.get("state", None))
|
||||||
@ -171,6 +180,7 @@ def track_state(
|
|||||||
comment=f"updated the state to {new_state.name}",
|
comment=f"updated the state to {new_state.name}",
|
||||||
old_identifier=old_state.id,
|
old_identifier=old_state.id,
|
||||||
new_identifier=new_state.id,
|
new_identifier=new_state.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -183,6 +193,7 @@ def track_description(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("description_html") != requested_data.get(
|
if current_instance.get("description_html") != requested_data.get(
|
||||||
"description_html"
|
"description_html"
|
||||||
@ -203,6 +214,7 @@ def track_description(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the description to {requested_data.get('description_html')}",
|
comment=f"updated the description to {requested_data.get('description_html')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -215,6 +227,7 @@ def track_target_date(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("target_date") != requested_data.get("target_date"):
|
if current_instance.get("target_date") != requested_data.get("target_date"):
|
||||||
if requested_data.get("target_date") == None:
|
if requested_data.get("target_date") == None:
|
||||||
@ -229,6 +242,7 @@ def track_target_date(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the target date to None",
|
comment=f"updated the target date to None",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -243,6 +257,7 @@ def track_target_date(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the target date to {requested_data.get('target_date')}",
|
comment=f"updated the target date to {requested_data.get('target_date')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -255,6 +270,7 @@ def track_start_date(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("start_date") != requested_data.get("start_date"):
|
if current_instance.get("start_date") != requested_data.get("start_date"):
|
||||||
if requested_data.get("start_date") == None:
|
if requested_data.get("start_date") == None:
|
||||||
@ -269,6 +285,7 @@ def track_start_date(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the start date to None",
|
comment=f"updated the start date to None",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -283,6 +300,7 @@ def track_start_date(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the start date to {requested_data.get('start_date')}",
|
comment=f"updated the start date to {requested_data.get('start_date')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -295,6 +313,7 @@ def track_labels(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
# Label Addition
|
# Label Addition
|
||||||
if len(requested_data.get("labels_list")) > len(current_instance.get("labels")):
|
if len(requested_data.get("labels_list")) > len(current_instance.get("labels")):
|
||||||
@ -314,6 +333,7 @@ def track_labels(
|
|||||||
comment=f"added label {label.name}",
|
comment=f"added label {label.name}",
|
||||||
new_identifier=label.id,
|
new_identifier=label.id,
|
||||||
old_identifier=None,
|
old_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -335,6 +355,7 @@ def track_labels(
|
|||||||
comment=f"removed label {label.name}",
|
comment=f"removed label {label.name}",
|
||||||
old_identifier=label.id,
|
old_identifier=label.id,
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -347,6 +368,7 @@ def track_assignees(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
):
|
):
|
||||||
# Assignee Addition
|
# Assignee Addition
|
||||||
if len(requested_data.get("assignees_list")) > len(
|
if len(requested_data.get("assignees_list")) > len(
|
||||||
@ -367,6 +389,7 @@ def track_assignees(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"added assignee {assignee.display_name}",
|
comment=f"added assignee {assignee.display_name}",
|
||||||
new_identifier=assignee.id,
|
new_identifier=assignee.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -389,12 +412,13 @@ def track_assignees(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"removed assignee {assignee.display_name}",
|
comment=f"removed assignee {assignee.display_name}",
|
||||||
old_identifier=assignee.id,
|
old_identifier=assignee.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_issue_activity(
|
def create_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -404,12 +428,13 @@ def create_issue_activity(
|
|||||||
comment=f"created the issue",
|
comment=f"created the issue",
|
||||||
verb="created",
|
verb="created",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def track_estimate_points(
|
def track_estimate_points(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
if current_instance.get("estimate_point") != requested_data.get("estimate_point"):
|
if current_instance.get("estimate_point") != requested_data.get("estimate_point"):
|
||||||
if requested_data.get("estimate_point") == None:
|
if requested_data.get("estimate_point") == None:
|
||||||
@ -424,6 +449,7 @@ def track_estimate_points(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the estimate point to None",
|
comment=f"updated the estimate point to None",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -438,12 +464,13 @@ def track_estimate_points(
|
|||||||
project=project,
|
project=project,
|
||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"updated the estimate point to {requested_data.get('estimate_point')}",
|
comment=f"updated the estimate point to {requested_data.get('estimate_point')}",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def track_archive_at(
|
def track_archive_at(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
if requested_data.get("archived_at") is None:
|
if requested_data.get("archived_at") is None:
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
@ -457,6 +484,7 @@ def track_archive_at(
|
|||||||
field="archived_at",
|
field="archived_at",
|
||||||
old_value="archive",
|
old_value="archive",
|
||||||
new_value="restore",
|
new_value="restore",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -471,12 +499,13 @@ def track_archive_at(
|
|||||||
field="archived_at",
|
field="archived_at",
|
||||||
old_value=None,
|
old_value=None,
|
||||||
new_value="archive",
|
new_value="archive",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def track_closed_to(
|
def track_closed_to(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
if requested_data.get("closed_to") is not None:
|
if requested_data.get("closed_to") is not None:
|
||||||
updated_state = State.objects.get(
|
updated_state = State.objects.get(
|
||||||
@ -496,12 +525,13 @@ def track_closed_to(
|
|||||||
comment=f"Plane updated the state to {updated_state.name}",
|
comment=f"Plane updated the state to {updated_state.name}",
|
||||||
old_identifier=None,
|
old_identifier=None,
|
||||||
new_identifier=updated_state.id,
|
new_identifier=updated_state.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_issue_activity(
|
def update_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
ISSUE_ACTIVITY_MAPPER = {
|
ISSUE_ACTIVITY_MAPPER = {
|
||||||
"name": track_name,
|
"name": track_name,
|
||||||
@ -518,6 +548,11 @@ def update_issue_activity(
|
|||||||
"closed_to": track_closed_to,
|
"closed_to": track_closed_to,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
|
current_instance = (
|
||||||
|
json.loads(current_instance) if current_instance is not None else None
|
||||||
|
)
|
||||||
|
|
||||||
for key in requested_data:
|
for key in requested_data:
|
||||||
func = ISSUE_ACTIVITY_MAPPER.get(key, None)
|
func = ISSUE_ACTIVITY_MAPPER.get(key, None)
|
||||||
if func is not None:
|
if func is not None:
|
||||||
@ -528,11 +563,12 @@ def update_issue_activity(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_issue_activity(
|
def delete_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -542,12 +578,13 @@ def delete_issue_activity(
|
|||||||
verb="deleted",
|
verb="deleted",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
field="issue",
|
field="issue",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_comment_activity(
|
def create_comment_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -566,12 +603,13 @@ def create_comment_activity(
|
|||||||
new_value=requested_data.get("comment_html", ""),
|
new_value=requested_data.get("comment_html", ""),
|
||||||
new_identifier=requested_data.get("id", None),
|
new_identifier=requested_data.get("id", None),
|
||||||
issue_comment_id=requested_data.get("id", None),
|
issue_comment_id=requested_data.get("id", None),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_comment_activity(
|
def update_comment_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -593,12 +631,13 @@ def update_comment_activity(
|
|||||||
new_value=requested_data.get("comment_html", ""),
|
new_value=requested_data.get("comment_html", ""),
|
||||||
new_identifier=current_instance.get("id", None),
|
new_identifier=current_instance.get("id", None),
|
||||||
issue_comment_id=current_instance.get("id", None),
|
issue_comment_id=current_instance.get("id", None),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_comment_activity(
|
def delete_comment_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -609,12 +648,13 @@ def delete_comment_activity(
|
|||||||
verb="deleted",
|
verb="deleted",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
field="comment",
|
field="comment",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_cycle_issue_activity(
|
def create_cycle_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -646,6 +686,7 @@ def create_cycle_issue_activity(
|
|||||||
comment=f"updated cycle from {old_cycle.name} to {new_cycle.name}",
|
comment=f"updated cycle from {old_cycle.name} to {new_cycle.name}",
|
||||||
old_identifier=old_cycle.id,
|
old_identifier=old_cycle.id,
|
||||||
new_identifier=new_cycle.id,
|
new_identifier=new_cycle.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -666,12 +707,13 @@ def create_cycle_issue_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"added cycle {cycle.name}",
|
comment=f"added cycle {cycle.name}",
|
||||||
new_identifier=cycle.id,
|
new_identifier=cycle.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_cycle_issue_activity(
|
def delete_cycle_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -695,12 +737,13 @@ def delete_cycle_issue_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"removed this issue from {cycle.name if cycle is not None else None}",
|
comment=f"removed this issue from {cycle.name if cycle is not None else None}",
|
||||||
old_identifier=cycle.id if cycle is not None else None,
|
old_identifier=cycle.id if cycle is not None else None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_module_issue_activity(
|
def create_module_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -732,6 +775,7 @@ def create_module_issue_activity(
|
|||||||
comment=f"updated module from {old_module.name} to {new_module.name}",
|
comment=f"updated module from {old_module.name} to {new_module.name}",
|
||||||
old_identifier=old_module.id,
|
old_identifier=old_module.id,
|
||||||
new_identifier=new_module.id,
|
new_identifier=new_module.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -751,12 +795,13 @@ def create_module_issue_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"added module {module.name}",
|
comment=f"added module {module.name}",
|
||||||
new_identifier=module.id,
|
new_identifier=module.id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_module_issue_activity(
|
def delete_module_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -780,12 +825,13 @@ def delete_module_issue_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f"removed this issue from {module.name if module is not None else None}",
|
comment=f"removed this issue from {module.name if module is not None else None}",
|
||||||
old_identifier=module.id if module is not None else None,
|
old_identifier=module.id if module is not None else None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_link_activity(
|
def create_link_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -803,12 +849,13 @@ def create_link_activity(
|
|||||||
field="link",
|
field="link",
|
||||||
new_value=requested_data.get("url", ""),
|
new_value=requested_data.get("url", ""),
|
||||||
new_identifier=requested_data.get("id", None),
|
new_identifier=requested_data.get("id", None),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_link_activity(
|
def update_link_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -829,12 +876,13 @@ def update_link_activity(
|
|||||||
old_identifier=current_instance.get("id"),
|
old_identifier=current_instance.get("id"),
|
||||||
new_value=requested_data.get("url", ""),
|
new_value=requested_data.get("url", ""),
|
||||||
new_identifier=current_instance.get("id", None),
|
new_identifier=current_instance.get("id", None),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_link_activity(
|
def delete_link_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
|
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -851,13 +899,14 @@ def delete_link_activity(
|
|||||||
actor=actor,
|
actor=actor,
|
||||||
field="link",
|
field="link",
|
||||||
old_value=current_instance.get("url", ""),
|
old_value=current_instance.get("url", ""),
|
||||||
new_value=""
|
new_value="",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_attachment_activity(
|
def create_attachment_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -875,12 +924,13 @@ def create_attachment_activity(
|
|||||||
field="attachment",
|
field="attachment",
|
||||||
new_value=current_instance.get("asset", ""),
|
new_value=current_instance.get("asset", ""),
|
||||||
new_identifier=current_instance.get("id", None),
|
new_identifier=current_instance.get("id", None),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_attachment_activity(
|
def delete_attachment_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -891,11 +941,12 @@ def delete_attachment_activity(
|
|||||||
verb="deleted",
|
verb="deleted",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
field="attachment",
|
field="attachment",
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_issue_reaction_activity(
|
def create_issue_reaction_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
if requested_data and requested_data.get("reaction") is not None:
|
if requested_data and requested_data.get("reaction") is not None:
|
||||||
@ -914,12 +965,13 @@ def create_issue_reaction_activity(
|
|||||||
comment="added the reaction",
|
comment="added the reaction",
|
||||||
old_identifier=None,
|
old_identifier=None,
|
||||||
new_identifier=issue_reaction,
|
new_identifier=issue_reaction,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_issue_reaction_activity(
|
def delete_issue_reaction_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
current_instance = (
|
current_instance = (
|
||||||
json.loads(current_instance) if current_instance is not None else None
|
json.loads(current_instance) if current_instance is not None else None
|
||||||
@ -938,12 +990,13 @@ def delete_issue_reaction_activity(
|
|||||||
comment="removed the reaction",
|
comment="removed the reaction",
|
||||||
old_identifier=current_instance.get("identifier"),
|
old_identifier=current_instance.get("identifier"),
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_comment_reaction_activity(
|
def create_comment_reaction_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
if requested_data and requested_data.get("reaction") is not None:
|
if requested_data and requested_data.get("reaction") is not None:
|
||||||
@ -963,12 +1016,13 @@ def create_comment_reaction_activity(
|
|||||||
comment="added the reaction",
|
comment="added the reaction",
|
||||||
old_identifier=None,
|
old_identifier=None,
|
||||||
new_identifier=comment_reaction_id,
|
new_identifier=comment_reaction_id,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_comment_reaction_activity(
|
def delete_comment_reaction_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
current_instance = (
|
current_instance = (
|
||||||
json.loads(current_instance) if current_instance is not None else None
|
json.loads(current_instance) if current_instance is not None else None
|
||||||
@ -989,12 +1043,13 @@ def delete_comment_reaction_activity(
|
|||||||
comment="removed the reaction",
|
comment="removed the reaction",
|
||||||
old_identifier=current_instance.get("identifier"),
|
old_identifier=current_instance.get("identifier"),
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_issue_vote_activity(
|
def create_issue_vote_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
if requested_data and requested_data.get("vote") is not None:
|
if requested_data and requested_data.get("vote") is not None:
|
||||||
@ -1011,12 +1066,13 @@ def create_issue_vote_activity(
|
|||||||
comment="added the vote",
|
comment="added the vote",
|
||||||
old_identifier=None,
|
old_identifier=None,
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_issue_vote_activity(
|
def delete_issue_vote_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
current_instance = (
|
current_instance = (
|
||||||
json.loads(current_instance) if current_instance is not None else None
|
json.loads(current_instance) if current_instance is not None else None
|
||||||
@ -1035,12 +1091,13 @@ def delete_issue_vote_activity(
|
|||||||
comment="removed the vote",
|
comment="removed the vote",
|
||||||
old_identifier=current_instance.get("identifier"),
|
old_identifier=current_instance.get("identifier"),
|
||||||
new_identifier=None,
|
new_identifier=None,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_issue_relation_activity(
|
def create_issue_relation_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -1080,12 +1137,13 @@ def create_issue_relation_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f'added {issue_relation.get("relation_type")} relation',
|
comment=f'added {issue_relation.get("relation_type")} relation',
|
||||||
old_identifier=issue_relation.get("related_issue"),
|
old_identifier=issue_relation.get("related_issue"),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def delete_issue_relation_activity(
|
def delete_issue_relation_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -1109,6 +1167,7 @@ def delete_issue_relation_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f'deleted {relation_type} relation',
|
comment=f'deleted {relation_type} relation',
|
||||||
old_identifier=current_instance.get("issue"),
|
old_identifier=current_instance.get("issue"),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
issue = Issue.objects.get(pk=current_instance.get("related_issue"))
|
issue = Issue.objects.get(pk=current_instance.get("related_issue"))
|
||||||
@ -1124,12 +1183,13 @@ def delete_issue_relation_activity(
|
|||||||
workspace=project.workspace,
|
workspace=project.workspace,
|
||||||
comment=f'deleted {current_instance.get("relation_type")} relation',
|
comment=f'deleted {current_instance.get("relation_type")} relation',
|
||||||
old_identifier=current_instance.get("related_issue"),
|
old_identifier=current_instance.get("related_issue"),
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_draft_issue_activity(
|
def create_draft_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -1140,12 +1200,13 @@ def create_draft_issue_activity(
|
|||||||
field="draft",
|
field="draft",
|
||||||
verb="created",
|
verb="created",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_draft_issue_activity(
|
def update_draft_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
requested_data = json.loads(requested_data) if requested_data is not None else None
|
requested_data = json.loads(requested_data) if requested_data is not None else None
|
||||||
current_instance = (
|
current_instance = (
|
||||||
@ -1160,6 +1221,7 @@ def update_draft_issue_activity(
|
|||||||
comment=f"created the issue",
|
comment=f"created the issue",
|
||||||
verb="updated",
|
verb="updated",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -1172,13 +1234,14 @@ def update_draft_issue_activity(
|
|||||||
field="draft",
|
field="draft",
|
||||||
verb="updated",
|
verb="updated",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def delete_draft_issue_activity(
|
def delete_draft_issue_activity(
|
||||||
requested_data, current_instance, issue_id, project, actor, issue_activities
|
requested_data, current_instance, issue_id, project, actor, issue_activities, epoch
|
||||||
):
|
):
|
||||||
issue_activities.append(
|
issue_activities.append(
|
||||||
IssueActivity(
|
IssueActivity(
|
||||||
@ -1188,6 +1251,7 @@ def delete_draft_issue_activity(
|
|||||||
field="draft",
|
field="draft",
|
||||||
verb="deleted",
|
verb="deleted",
|
||||||
actor=actor,
|
actor=actor,
|
||||||
|
epoch=epoch,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1200,6 +1264,7 @@ def issue_activity(
|
|||||||
issue_id,
|
issue_id,
|
||||||
actor_id,
|
actor_id,
|
||||||
project_id,
|
project_id,
|
||||||
|
epoch,
|
||||||
subscriber=True,
|
subscriber=True,
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
@ -1276,6 +1341,7 @@ def issue_activity(
|
|||||||
project,
|
project,
|
||||||
actor,
|
actor,
|
||||||
issue_activities,
|
issue_activities,
|
||||||
|
epoch,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Save all the values to database
|
# Save all the values to database
|
||||||
|
@ -77,6 +77,7 @@ def archive_old_issues():
|
|||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
subscriber=False,
|
subscriber=False,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
for issue in updated_issues
|
for issue in updated_issues
|
||||||
]
|
]
|
||||||
@ -148,6 +149,7 @@ def close_old_issues():
|
|||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
current_instance=None,
|
current_instance=None,
|
||||||
subscriber=False,
|
subscriber=False,
|
||||||
|
epoch = int(timezone.now().timestamp())
|
||||||
)
|
)
|
||||||
for issue in updated_issues
|
for issue in updated_issues
|
||||||
]
|
]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
def update_issue_activity(apps, schema_editor):
|
def update_issue_activity(apps, schema_editor):
|
||||||
IssueActivityModel = apps.get_model("db", "IssueActivity")
|
IssueActivityModel = apps.get_model("db", "IssueActivity")
|
||||||
updated_issue_activity = []
|
updated_issue_activity = []
|
||||||
|
53
apiserver/plane/db/migrations/0046_auto_20230919_1421.py
Normal file
53
apiserver/plane/db/migrations/0046_auto_20230919_1421.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Generated by Django 4.2.3 on 2023-09-19 14:21
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def update_epoch(apps, schema_editor):
|
||||||
|
IssueActivity = apps.get_model('db', 'IssueActivity')
|
||||||
|
updated_issue_activity = []
|
||||||
|
for obj in IssueActivity.objects.all():
|
||||||
|
obj.epoch = int(obj.created_at.timestamp())
|
||||||
|
updated_issue_activity.append(obj)
|
||||||
|
IssueActivity.objects.bulk_update(updated_issue_activity, ["epoch"], batch_size=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('db', '0045_auto_20230915_0655'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='GlobalView',
|
||||||
|
fields=[
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Last Modified At')),
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='View Name')),
|
||||||
|
('description', models.TextField(blank=True, verbose_name='View Description')),
|
||||||
|
('query', models.JSONField(verbose_name='View Query')),
|
||||||
|
('access', models.PositiveSmallIntegerField(choices=[(0, 'Private'), (1, 'Public')], default=1)),
|
||||||
|
('query_data', models.JSONField(default=dict)),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
|
||||||
|
('updated_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Last Modified By')),
|
||||||
|
('workspace', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='global_views', to='db.workspace')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Global View',
|
||||||
|
'verbose_name_plural': 'Global Views',
|
||||||
|
'db_table': 'global_views',
|
||||||
|
'ordering': ('-created_at',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='issueactivity',
|
||||||
|
name='epoch',
|
||||||
|
field=models.FloatField(null=True),
|
||||||
|
),
|
||||||
|
migrations.RunPython(update_epoch),
|
||||||
|
]
|
@ -50,7 +50,7 @@ from .state import State
|
|||||||
|
|
||||||
from .cycle import Cycle, CycleIssue, CycleFavorite
|
from .cycle import Cycle, CycleIssue, CycleFavorite
|
||||||
|
|
||||||
from .view import IssueView, IssueViewFavorite
|
from .view import GlobalView, IssueView, IssueViewFavorite
|
||||||
|
|
||||||
from .module import Module, ModuleMember, ModuleIssue, ModuleLink, ModuleFavorite
|
from .module import Module, ModuleMember, ModuleIssue, ModuleLink, ModuleFavorite
|
||||||
|
|
||||||
|
@ -309,6 +309,7 @@ class IssueActivity(ProjectBaseModel):
|
|||||||
)
|
)
|
||||||
old_identifier = models.UUIDField(null=True)
|
old_identifier = models.UUIDField(null=True)
|
||||||
new_identifier = models.UUIDField(null=True)
|
new_identifier = models.UUIDField(null=True)
|
||||||
|
epoch = models.FloatField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Issue Activity"
|
verbose_name = "Issue Activity"
|
||||||
|
@ -3,7 +3,30 @@ from django.db import models
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
# Module import
|
# Module import
|
||||||
from . import ProjectBaseModel
|
from . import ProjectBaseModel, BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalView(BaseModel):
|
||||||
|
workspace = models.ForeignKey(
|
||||||
|
"db.Workspace", on_delete=models.CASCADE, related_name="global_views"
|
||||||
|
)
|
||||||
|
name = models.CharField(max_length=255, verbose_name="View Name")
|
||||||
|
description = models.TextField(verbose_name="View Description", blank=True)
|
||||||
|
query = models.JSONField(verbose_name="View Query")
|
||||||
|
access = models.PositiveSmallIntegerField(
|
||||||
|
default=1, choices=((0, "Private"), (1, "Public"))
|
||||||
|
)
|
||||||
|
query_data = models.JSONField(default=dict)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Global View"
|
||||||
|
verbose_name_plural = "Global Views"
|
||||||
|
db_table = "global_views"
|
||||||
|
ordering = ("-created_at",)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return name of the View"""
|
||||||
|
return f"{self.name} <{self.workspace.name}>"
|
||||||
|
|
||||||
|
|
||||||
class IssueView(ProjectBaseModel):
|
class IssueView(ProjectBaseModel):
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
"""Production settings and globals."""
|
"""Production settings and globals."""
|
||||||
from urllib.parse import urlparse
|
|
||||||
import ssl
|
import ssl
|
||||||
import certifi
|
import certifi
|
||||||
|
|
||||||
import dj_database_url
|
import dj_database_url
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
@ -91,29 +89,6 @@ if bool(os.environ.get("SENTRY_DSN", False)):
|
|||||||
profiles_sample_rate=1.0,
|
profiles_sample_rate=1.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
if DOCKERIZED and USE_MINIO:
|
|
||||||
INSTALLED_APPS += ("storages",)
|
|
||||||
STORAGES["default"] = {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"}
|
|
||||||
# The AWS access key to use.
|
|
||||||
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "access-key")
|
|
||||||
# The AWS secret access key to use.
|
|
||||||
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "secret-key")
|
|
||||||
# The name of the bucket to store files in.
|
|
||||||
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME", "uploads")
|
|
||||||
# The full URL to the S3 endpoint. Leave blank to use the default region URL.
|
|
||||||
AWS_S3_ENDPOINT_URL = os.environ.get(
|
|
||||||
"AWS_S3_ENDPOINT_URL", "http://plane-minio:9000"
|
|
||||||
)
|
|
||||||
# Default permissions
|
|
||||||
AWS_DEFAULT_ACL = "public-read"
|
|
||||||
AWS_QUERYSTRING_AUTH = False
|
|
||||||
AWS_S3_FILE_OVERWRITE = False
|
|
||||||
|
|
||||||
# Custom Domain settings
|
|
||||||
parsed_url = urlparse(os.environ.get("WEB_URL", "http://localhost"))
|
|
||||||
AWS_S3_CUSTOM_DOMAIN = f"{parsed_url.netloc}/{AWS_STORAGE_BUCKET_NAME}"
|
|
||||||
AWS_S3_URL_PROTOCOL = f"{parsed_url.scheme}:"
|
|
||||||
else:
|
|
||||||
# The AWS region to connect to.
|
# The AWS region to connect to.
|
||||||
AWS_REGION = os.environ.get("AWS_REGION", "")
|
AWS_REGION = os.environ.get("AWS_REGION", "")
|
||||||
|
|
||||||
@ -218,17 +193,6 @@ CSRF_COOKIE_SECURE = True
|
|||||||
|
|
||||||
REDIS_URL = os.environ.get("REDIS_URL")
|
REDIS_URL = os.environ.get("REDIS_URL")
|
||||||
|
|
||||||
if DOCKERIZED:
|
|
||||||
CACHES = {
|
|
||||||
"default": {
|
|
||||||
"BACKEND": "django_redis.cache.RedisCache",
|
|
||||||
"LOCATION": REDIS_URL,
|
|
||||||
"OPTIONS": {
|
|
||||||
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django_redis.cache.RedisCache",
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
@ -261,19 +225,16 @@ broker_url = (
|
|||||||
f"{redis_url}?ssl_cert_reqs={ssl.CERT_NONE.name}&ssl_ca_certs={certifi.where()}"
|
f"{redis_url}?ssl_cert_reqs={ssl.CERT_NONE.name}&ssl_ca_certs={certifi.where()}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if DOCKERIZED:
|
|
||||||
CELERY_BROKER_URL = REDIS_URL
|
|
||||||
CELERY_RESULT_BACKEND = REDIS_URL
|
|
||||||
else:
|
|
||||||
CELERY_RESULT_BACKEND = broker_url
|
CELERY_RESULT_BACKEND = broker_url
|
||||||
CELERY_BROKER_URL = broker_url
|
CELERY_BROKER_URL = broker_url
|
||||||
|
|
||||||
GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False)
|
GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False)
|
||||||
|
|
||||||
|
# Enable or Disable signups
|
||||||
ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1"
|
ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1"
|
||||||
|
|
||||||
# Scout Settings
|
# Scout Settings
|
||||||
SCOUT_MONITOR = os.environ.get("SCOUT_MONITOR", False)
|
SCOUT_MONITOR = os.environ.get("SCOUT_MONITOR", False)
|
||||||
SCOUT_KEY = os.environ.get("SCOUT_KEY", "")
|
SCOUT_KEY = os.environ.get("SCOUT_KEY", "")
|
||||||
SCOUT_NAME = "Plane"
|
SCOUT_NAME = "Plane"
|
||||||
|
|
||||||
|
128
apiserver/plane/settings/selfhosted.py
Normal file
128
apiserver/plane/settings/selfhosted.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
"""Self hosted settings and globals."""
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import dj_database_url
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
|
from .common import * # noqa
|
||||||
|
|
||||||
|
# Database
|
||||||
|
DEBUG = int(os.environ.get("DEBUG", 0)) == 1
|
||||||
|
|
||||||
|
# Docker configurations
|
||||||
|
DOCKERIZED = 1
|
||||||
|
USE_MINIO = 1
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
"default": {
|
||||||
|
"ENGINE": "django.db.backends.postgresql",
|
||||||
|
"NAME": "plane",
|
||||||
|
"USER": os.environ.get("PGUSER", ""),
|
||||||
|
"PASSWORD": os.environ.get("PGPASSWORD", ""),
|
||||||
|
"HOST": os.environ.get("PGHOST", ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse database configuration from $DATABASE_URL
|
||||||
|
DATABASES["default"] = dj_database_url.config()
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
# File size limit
|
||||||
|
FILE_SIZE_LIMIT = int(os.environ.get("FILE_SIZE_LIMIT", 5242880))
|
||||||
|
|
||||||
|
CORS_ALLOW_METHODS = [
|
||||||
|
"DELETE",
|
||||||
|
"GET",
|
||||||
|
"OPTIONS",
|
||||||
|
"PATCH",
|
||||||
|
"POST",
|
||||||
|
"PUT",
|
||||||
|
]
|
||||||
|
|
||||||
|
CORS_ALLOW_HEADERS = [
|
||||||
|
"accept",
|
||||||
|
"accept-encoding",
|
||||||
|
"authorization",
|
||||||
|
"content-type",
|
||||||
|
"dnt",
|
||||||
|
"origin",
|
||||||
|
"user-agent",
|
||||||
|
"x-csrftoken",
|
||||||
|
"x-requested-with",
|
||||||
|
]
|
||||||
|
|
||||||
|
CORS_ALLOW_CREDENTIALS = True
|
||||||
|
CORS_ALLOW_ALL_ORIGINS = True
|
||||||
|
|
||||||
|
STORAGES = {
|
||||||
|
"staticfiles": {
|
||||||
|
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTALLED_APPS += ("storages",)
|
||||||
|
STORAGES["default"] = {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"}
|
||||||
|
# The AWS access key to use.
|
||||||
|
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "access-key")
|
||||||
|
# The AWS secret access key to use.
|
||||||
|
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "secret-key")
|
||||||
|
# The name of the bucket to store files in.
|
||||||
|
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME", "uploads")
|
||||||
|
# The full URL to the S3 endpoint. Leave blank to use the default region URL.
|
||||||
|
AWS_S3_ENDPOINT_URL = os.environ.get(
|
||||||
|
"AWS_S3_ENDPOINT_URL", "http://plane-minio:9000"
|
||||||
|
)
|
||||||
|
# Default permissions
|
||||||
|
AWS_DEFAULT_ACL = "public-read"
|
||||||
|
AWS_QUERYSTRING_AUTH = False
|
||||||
|
AWS_S3_FILE_OVERWRITE = False
|
||||||
|
|
||||||
|
# Custom Domain settings
|
||||||
|
parsed_url = urlparse(os.environ.get("WEB_URL", "http://localhost"))
|
||||||
|
AWS_S3_CUSTOM_DOMAIN = f"{parsed_url.netloc}/{AWS_STORAGE_BUCKET_NAME}"
|
||||||
|
AWS_S3_URL_PROTOCOL = f"{parsed_url.scheme}:"
|
||||||
|
|
||||||
|
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
|
||||||
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||||
|
|
||||||
|
# Allow all host headers
|
||||||
|
ALLOWED_HOSTS = [
|
||||||
|
"*",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
SESSION_COOKIE_SECURE = True
|
||||||
|
CSRF_COOKIE_SECURE = True
|
||||||
|
|
||||||
|
# Redis URL
|
||||||
|
REDIS_URL = os.environ.get("REDIS_URL")
|
||||||
|
|
||||||
|
# Caches
|
||||||
|
CACHES = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
|
"LOCATION": REDIS_URL,
|
||||||
|
"OPTIONS": {
|
||||||
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# URL used for email redirects
|
||||||
|
WEB_URL = os.environ.get("WEB_URL", "http://localhost")
|
||||||
|
|
||||||
|
# Celery settings
|
||||||
|
CELERY_BROKER_URL = REDIS_URL
|
||||||
|
CELERY_RESULT_BACKEND = REDIS_URL
|
||||||
|
|
||||||
|
# Enable or Disable signups
|
||||||
|
ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1"
|
||||||
|
|
||||||
|
# Analytics
|
||||||
|
ANALYTICS_BASE_API = False
|
||||||
|
|
||||||
|
# OPEN AI Settings
|
||||||
|
OPENAI_API_BASE = os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1")
|
||||||
|
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", False)
|
||||||
|
GPT_ENGINE = os.environ.get("GPT_ENGINE", "gpt-3.5-turbo")
|
@ -4,7 +4,7 @@ x-api-and-worker-env:
|
|||||||
&api-and-worker-env
|
&api-and-worker-env
|
||||||
DEBUG: ${DEBUG}
|
DEBUG: ${DEBUG}
|
||||||
SENTRY_DSN: ${SENTRY_DSN}
|
SENTRY_DSN: ${SENTRY_DSN}
|
||||||
DJANGO_SETTINGS_MODULE: plane.settings.production
|
DJANGO_SETTINGS_MODULE: plane.settings.selfhosted
|
||||||
DATABASE_URL: postgres://${PGUSER}:${PGPASSWORD}@${PGHOST}:5432/${PGDATABASE}
|
DATABASE_URL: postgres://${PGUSER}:${PGPASSWORD}@${PGHOST}:5432/${PGDATABASE}
|
||||||
REDIS_URL: redis://plane-redis:6379/
|
REDIS_URL: redis://plane-redis:6379/
|
||||||
EMAIL_HOST: ${EMAIL_HOST}
|
EMAIL_HOST: ${EMAIL_HOST}
|
||||||
|
Loading…
Reference in New Issue
Block a user