diff --git a/apiserver/plane/api/views/module.py b/apiserver/plane/api/views/module.py index 8c374baf6bd..67ccf13a9f3 100644 --- a/apiserver/plane/api/views/module.py +++ b/apiserver/plane/api/views/module.py @@ -298,7 +298,11 @@ def delete(self, request, slug, project_id, pk): actor_id=str(request.user.id), issue_id=None, project_id=str(project_id), - current_instance=None, + current_instance=json.dumps( + { + "module_name": str(module.name), + } + ), epoch=int(timezone.now().timestamp()), ) module.delete() diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index ecc83630f21..d874451f48c 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -378,6 +378,7 @@ def retrieve(self, request, slug, project_id, pk): data = ( self.get_queryset() .filter(pk=pk) + .filter(archived_at__isnull=True) .annotate( sub_issues=Issue.issue_objects.filter( project_id=self.kwargs.get("project_id"), @@ -416,6 +417,13 @@ def retrieve(self, request, slug, project_id, pk): ) .first() ) + + if data is None: + return Response( + {"error": "Cycle not found"}, + status=status.HTTP_404_NOT_FOUND, + ) + queryset = queryset.first() recent_visited_task.delay( diff --git a/apiserver/plane/app/views/inbox/base.py b/apiserver/plane/app/views/inbox/base.py index b99c44f1d94..08a6acbce6e 100644 --- a/apiserver/plane/app/views/inbox/base.py +++ b/apiserver/plane/app/views/inbox/base.py @@ -16,9 +16,7 @@ # Module imports from ..base import BaseViewSet -from plane.app.permissions import ( - allow_permission, ROLE -) +from plane.app.permissions import allow_permission, ROLE from plane.db.models import ( Inbox, InboxIssue, @@ -169,9 +167,9 @@ def get_queryset(self): @allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.VIEWER, ROLE.GUEST]) def list(self, request, slug, project_id): - inbox_id = Inbox.objects.filter( + inbox_id = Inbox.objects.get( workspace__slug=slug, project_id=project_id - ).first() + ) filters = issue_filters(request.GET, "GET", "issue__") inbox_issue = ( InboxIssue.objects.filter( @@ -522,9 +520,9 @@ def partial_update(self, request, slug, project_id, pk): model=Issue, ) def retrieve(self, request, slug, project_id, pk): - inbox_id = Inbox.objects.filter( + inbox_id = Inbox.objects.get( workspace__slug=slug, project_id=project_id - ).first() + ) inbox_issue = ( InboxIssue.objects.select_related("issue") .prefetch_related( diff --git a/apiserver/plane/bgtasks/email_notification_task.py b/apiserver/plane/bgtasks/email_notification_task.py index fa154828b84..11ec91eb4ce 100644 --- a/apiserver/plane/bgtasks/email_notification_task.py +++ b/apiserver/plane/bgtasks/email_notification_task.py @@ -161,6 +161,8 @@ def process_mention(mention_component): def process_html_content(content): + if content is None: + return None processed_content_list = [] for html_content in content: processed_content = process_mention(html_content) diff --git a/apiserver/plane/bgtasks/export_task.py b/apiserver/plane/bgtasks/export_task.py index cfb6853a7e8..27d6ff4769f 100644 --- a/apiserver/plane/bgtasks/export_task.py +++ b/apiserver/plane/bgtasks/export_task.py @@ -174,7 +174,7 @@ def generate_table_row(issue): if issue["assignees__first_name"] and issue["assignees__last_name"] else "" ), - issue["labels__name"], + issue["labels__name"] if issue["labels__name"] else "", issue["issue_cycle__cycle__name"], dateConverter(issue["issue_cycle__cycle__start_date"]), dateConverter(issue["issue_cycle__cycle__end_date"]), @@ -207,7 +207,7 @@ def generate_json_row(issue): if issue["assignees__first_name"] and issue["assignees__last_name"] else "" ), - "Labels": issue["labels__name"], + "Labels": issue["labels__name"] if issue["labels__name"] else "", "Cycle Name": issue["issue_cycle__cycle__name"], "Cycle Start Date": dateConverter( issue["issue_cycle__cycle__start_date"] diff --git a/apiserver/plane/bgtasks/page_transaction_task.py b/apiserver/plane/bgtasks/page_transaction_task.py index e3cf81a6e7f..893bbf97233 100644 --- a/apiserver/plane/bgtasks/page_transaction_task.py +++ b/apiserver/plane/bgtasks/page_transaction_task.py @@ -10,6 +10,7 @@ # Module imports from plane.db.models import Page, PageLog from celery import shared_task +from plane.utils.exception_logger import log_exception def extract_components(value, tag): @@ -34,42 +35,48 @@ def extract_components(value, tag): @shared_task def page_transaction(new_value, old_value, page_id): - page = Page.objects.get(pk=page_id) - new_page_mention = PageLog.objects.filter(page_id=page_id).exists() - - old_value = json.loads(old_value) if old_value else {} - - new_transactions = [] - deleted_transaction_ids = set() - - # TODO - Add "issue-embed-component", "img", "todo" components - components = ["mention-component"] - for component in components: - old_mentions = extract_components(old_value, component) - new_mentions = extract_components(new_value, component) - - new_mentions_ids = {mention["id"] for mention in new_mentions} - old_mention_ids = {mention["id"] for mention in old_mentions} - deleted_transaction_ids.update(old_mention_ids - new_mentions_ids) - - new_transactions.extend( - PageLog( - transaction=mention["id"], - page_id=page_id, - entity_identifier=mention["entity_identifier"], - entity_name=mention["entity_name"], - workspace_id=page.workspace_id, - created_at=timezone.now(), - updated_at=timezone.now(), + try: + page = Page.objects.get(pk=page_id) + new_page_mention = PageLog.objects.filter(page_id=page_id).exists() + + old_value = json.loads(old_value) if old_value else {} + + new_transactions = [] + deleted_transaction_ids = set() + + # TODO - Add "issue-embed-component", "img", "todo" components + components = ["mention-component"] + for component in components: + old_mentions = extract_components(old_value, component) + new_mentions = extract_components(new_value, component) + + new_mentions_ids = {mention["id"] for mention in new_mentions} + old_mention_ids = {mention["id"] for mention in old_mentions} + deleted_transaction_ids.update(old_mention_ids - new_mentions_ids) + + new_transactions.extend( + PageLog( + transaction=mention["id"], + page_id=page_id, + entity_identifier=mention["entity_identifier"], + entity_name=mention["entity_name"], + workspace_id=page.workspace_id, + created_at=timezone.now(), + updated_at=timezone.now(), + ) + for mention in new_mentions + if mention["id"] not in old_mention_ids or not new_page_mention ) - for mention in new_mentions - if mention["id"] not in old_mention_ids or not new_page_mention - ) - # Create new PageLog objects for new transactions - PageLog.objects.bulk_create( - new_transactions, batch_size=10, ignore_conflicts=True - ) + # Create new PageLog objects for new transactions + PageLog.objects.bulk_create( + new_transactions, batch_size=10, ignore_conflicts=True + ) - # Delete the removed transactions - PageLog.objects.filter(transaction__in=deleted_transaction_ids).delete() + # Delete the removed transactions + PageLog.objects.filter(transaction__in=deleted_transaction_ids).delete() + except Page.DoesNotExist: + return + except Exception as e: + log_exception(e) + return diff --git a/apiserver/plane/bgtasks/page_version_task.py b/apiserver/plane/bgtasks/page_version_task.py index d8be1974322..628fe62b72a 100644 --- a/apiserver/plane/bgtasks/page_version_task.py +++ b/apiserver/plane/bgtasks/page_version_task.py @@ -6,6 +6,7 @@ # Module imports from plane.db.models import Page, PageVersion +from plane.utils.exception_logger import log_exception @shared_task @@ -14,31 +15,39 @@ def page_version( existing_instance, user_id, ): - # Get the page - page = Page.objects.get(id=page_id) - - # Get the current instance - current_instance = ( - json.loads(existing_instance) if existing_instance is not None else {} - ) - - # Create a version if description_html is updated - if current_instance.get("description_html") != page.description_html: - # Create a new page version - PageVersion.objects.create( - page_id=page_id, - workspace_id=page.workspace_id, - description_html=page.description_html, - description_binary=page.description_binary, - owned_by_id=user_id, - last_saved_at=page.updated_at, + try: + # Get the page + page = Page.objects.get(id=page_id) + + # Get the current instance + current_instance = ( + json.loads(existing_instance) + if existing_instance is not None + else {} ) - # If page versions are greater than 20 delete the oldest one - if PageVersion.objects.filter(page_id=page_id).count() > 20: - # Delete the old page version - PageVersion.objects.filter(page_id=page_id).order_by( - "last_saved_at" - ).first().delete() - - return + # Create a version if description_html is updated + if current_instance.get("description_html") != page.description_html: + # Create a new page version + PageVersion.objects.create( + page_id=page_id, + workspace_id=page.workspace_id, + description_html=page.description_html, + description_binary=page.description_binary, + owned_by_id=user_id, + last_saved_at=page.updated_at, + ) + + # If page versions are greater than 20 delete the oldest one + if PageVersion.objects.filter(page_id=page_id).count() > 20: + # Delete the old page version + PageVersion.objects.filter(page_id=page_id).order_by( + "last_saved_at" + ).first().delete() + + return + except Page.DoesNotExist: + return + except Exception as e: + log_exception(e) + return diff --git a/apiserver/plane/bgtasks/webhook_task.py b/apiserver/plane/bgtasks/webhook_task.py index 6696a569c1a..7614c4b2f57 100644 --- a/apiserver/plane/bgtasks/webhook_task.py +++ b/apiserver/plane/bgtasks/webhook_task.py @@ -152,6 +152,8 @@ def webhook_task(self, webhook, slug, event, event_data, action, current_site): retry_count=str(self.request.retries), ) + except Webhook.DoesNotExist: + return except requests.RequestException as e: # Log the failed webhook request WebhookLog.objects.create(