From c2510d7532320c59142ee7927e891a5a03144f1a Mon Sep 17 00:00:00 2001 From: Amarendra Shendkar Date: Thu, 2 May 2024 13:59:28 +0530 Subject: [PATCH 01/80] fixed issues with alignment api --- ai-services/align-api/requirements.txt | 4 ++-- ai-services/align-api/src/wav2vec2/utils.py | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ai-services/align-api/requirements.txt b/ai-services/align-api/requirements.txt index f347b29a..26440aad 100644 --- a/ai-services/align-api/requirements.txt +++ b/ai-services/align-api/requirements.txt @@ -4,6 +4,6 @@ tensorboardX rich==12.6.0 srt==3.5.2 Cython==0.29.32 -urduhack==1.1.1 -fastapi['all'] +urduhack +fastapi indic-nlp-library \ No newline at end of file diff --git a/ai-services/align-api/src/wav2vec2/utils.py b/ai-services/align-api/src/wav2vec2/utils.py index b016bd56..38e403fb 100644 --- a/ai-services/align-api/src/wav2vec2/utils.py +++ b/ai-services/align-api/src/wav2vec2/utils.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from rich.console import Console from rich.traceback import install - +import os install() console = Console() @@ -35,8 +35,13 @@ def length(self): class Wav2vec2: def __init__(self, model_path, language_code, mode, device): - self.asr_path = glob(model_path + "/" + language_code + "/*.pt")[0] - self.dict_path = glob(model_path + "/" + language_code + "/*.txt")[0] + current_dir = os.path.dirname(os.path.abspath(__file__)) + two_levels_up = os.path.abspath(os.path.join(current_dir, "../../")) + model_loc = os.path.join(two_levels_up, os.path.join(model_path, language_code)) + + self.asr_path = glob(os.path.join( model_loc ,"*.pt"))[0] + self.dict_path = glob(os.path.join(model_loc, "*.txt"))[0] + self.device = device self.encoder = self.load_model_encoder() self.labels = self.get_labels() From 6455607434a96a23279a5356f7cba53e8c2b3449 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 10 Sep 2024 10:48:33 +0530 Subject: [PATCH 02/80] moving openai engine to env variables --- backend/utils/llm_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/utils/llm_api.py b/backend/utils/llm_api.py index 754b8116..e597905d 100644 --- a/backend/utils/llm_api.py +++ b/backend/utils/llm_api.py @@ -88,7 +88,7 @@ def get_gpt3_output(system_prompt=None, user_prompt=None, history=None): openai.api_base = os.getenv("LLM_INTERACTIONS_OPENAI_API_BASE") openai.api_version = os.getenv("LLM_INTERACTIONS_OPENAI_API_VERSION") openai.api_key = os.getenv("OPENAI_API_KEY") - engine = "prompt-chat-gpt35" + engine = os.getenv("LLM_INTERACTIONS_OPENAI_ENGINE") messages = [] if system_prompt: From 18d3716865cd2d7e32a102935a6d0aad89f87f4c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 10 Sep 2024 12:49:43 +0530 Subject: [PATCH 03/80] add status field to admin panel display for voiceover --- backend/project/views.py | 16 ++++++++-------- backend/voiceover/admin.py | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/project/views.py b/backend/project/views.py index 8eb00844..030e0fa4 100644 --- a/backend/project/views.py +++ b/backend/project/views.py @@ -803,12 +803,12 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): # filter data based on filter parameters all_tasks = task_filter_query(all_tasks, filter_dict) - if not ( - request.user in project.managers.all() - or request.user.is_superuser - or organization.organization_owners.filter(id=request.user.id).exists() - ): - all_tasks = all_tasks.filter(user=request.user).order_by(sort_by) + # if not ( + # request.user in project.managers.all() + # or request.user.is_superuser + # or organization.organization_owners.filter(id=request.user.id).exists() + # ): + # all_tasks = all_tasks.filter(user=request.user).order_by(sort_by) total_count = len(all_tasks) total_pages = math.ceil(total_count / int(limit)) @@ -843,7 +843,7 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): "Upload": False, "Info": False, "Reopen": False, - "Regenerate": False, + "Regenerate": True, } buttons["Update"] = True buttons["Delete"] = True @@ -922,7 +922,7 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): "Upload": False, "Info": False, "Reopen": False, - "Regenerate": False, + "Regenerate": True, } buttons["Update"] = True buttons["Delete"] = True diff --git a/backend/voiceover/admin.py b/backend/voiceover/admin.py index bbb4e052..944763ee 100644 --- a/backend/voiceover/admin.py +++ b/backend/voiceover/admin.py @@ -15,6 +15,7 @@ class VoiceOverAdmin(admin.ModelAdmin): "voice_over_type", "updated_at", "task", + "status", ) list_filter = ("video", "voice_over_type", "translation") search_fields = ("video", "voice_over_type", "translation") From a9a326de9148b50d4b2f342cc07ad0ceead21841 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 10 Sep 2024 12:51:33 +0530 Subject: [PATCH 04/80] add status field to admin panel display for voiceover --- backend/project/views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/project/views.py b/backend/project/views.py index 030e0fa4..8eb00844 100644 --- a/backend/project/views.py +++ b/backend/project/views.py @@ -803,12 +803,12 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): # filter data based on filter parameters all_tasks = task_filter_query(all_tasks, filter_dict) - # if not ( - # request.user in project.managers.all() - # or request.user.is_superuser - # or organization.organization_owners.filter(id=request.user.id).exists() - # ): - # all_tasks = all_tasks.filter(user=request.user).order_by(sort_by) + if not ( + request.user in project.managers.all() + or request.user.is_superuser + or organization.organization_owners.filter(id=request.user.id).exists() + ): + all_tasks = all_tasks.filter(user=request.user).order_by(sort_by) total_count = len(all_tasks) total_pages = math.ceil(total_count / int(limit)) @@ -843,7 +843,7 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): "Upload": False, "Info": False, "Reopen": False, - "Regenerate": True, + "Regenerate": False, } buttons["Update"] = True buttons["Delete"] = True @@ -922,7 +922,7 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): "Upload": False, "Info": False, "Reopen": False, - "Regenerate": True, + "Regenerate": False, } buttons["Update"] = True buttons["Delete"] = True From 6e1c2db0f6827c508dccb5bd27226195882e74a0 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 10 Sep 2024 12:59:02 +0530 Subject: [PATCH 05/80] add status field to admin panel display for trnaslation and transcription --- backend/transcript/admin.py | 2 +- backend/translation/admin.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/transcript/admin.py b/backend/transcript/admin.py index d35c6cb5..ee2282fd 100644 --- a/backend/transcript/admin.py +++ b/backend/transcript/admin.py @@ -5,7 +5,7 @@ # Show particular fields in the admin panel class TranscriptAdmin(admin.ModelAdmin): - list_display = ("task", "video", "language", "transcript_type", "updated_at", "id") + list_display = ("task", "video", "language", "transcript_type", "updated_at", "id", "status") list_filter = ("video", "language", "transcript_type") search_fields = ("video", "language", "transcript_type") ordering = ("-updated_at",) diff --git a/backend/translation/admin.py b/backend/translation/admin.py index 19114afa..4a521dcf 100644 --- a/backend/translation/admin.py +++ b/backend/translation/admin.py @@ -17,6 +17,7 @@ class TranslationAdmin(admin.ModelAdmin): "translation_type", "updated_at", "id", + "status", ) list_filter = ("task", "transcript", "target_language", "translation_type") search_fields = ("task", "transcript", "target_language", "translation_type") From 521e16b4eb1673bae3e4d89f91894261c45e4963 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 10 Sep 2024 17:27:33 +0530 Subject: [PATCH 06/80] fix support for upload of google drive video --- backend/translation/admin.py | 2 +- backend/video/utils.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/translation/admin.py b/backend/translation/admin.py index 4a521dcf..a143bf06 100644 --- a/backend/translation/admin.py +++ b/backend/translation/admin.py @@ -19,7 +19,7 @@ class TranslationAdmin(admin.ModelAdmin): "id", "status", ) - list_filter = ("task", "transcript", "target_language", "translation_type") + list_filter = ("task", "transcript", "target_language", "translation_type", "video") search_fields = ("task", "transcript", "target_language", "translation_type") ordering = ("-updated_at",) diff --git a/backend/video/utils.py b/backend/video/utils.py index f8a387cb..d1afe7aa 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -28,7 +28,7 @@ from googleapiclient.discovery import build import re -ydl = YoutubeDL({"format": "best*[acodec!=none]"}) +ydl = YoutubeDL({"format": "best"}) # Declare a global variable to save the object for Google Drive ID extraction drive_info_extractor = get_info_extractor("GoogleDrive")() @@ -526,11 +526,11 @@ def get_video_func(request): status=status.HTTP_400_BAD_REQUEST, ) - if title[-4:] == ".mp4" and "youtube.com" not in normalized_url: - return Response( - {"message": "Invalid file type. Mp4 is not supported"}, - status=status.HTTP_400_BAD_REQUEST, - ) + # if title[-4:] == ".mp4" and "youtube.com" not in normalized_url: + # return Response( + # {"message": "Invalid file type. Mp4 is not supported"}, + # status=status.HTTP_400_BAD_REQUEST, + # ) # Create a new DB entry if URL does not exist, else return the existing entry if create: video = Video.objects.create( From ccb68264e6bb6f6311acd2de30f71426811d7e02 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 12 Sep 2024 10:29:42 +0530 Subject: [PATCH 07/80] make emails lowercase while signup and login --- backend/backend/settings.py | 2 +- backend/users/managers.py | 6 +++--- backend/users/views.py | 7 +++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/backend/settings.py b/backend/backend/settings.py index ac1bd7c2..a5fe2f6c 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -97,7 +97,7 @@ PROTOCOL = "https" DJOSER = { - "PASSWORD_RESET_CONFIRM_URL": "forget-password/confirm/{uid}/{token}", + "PASSWORD_RESET_CONFIRM_URL": os.getenv("FRONTEND_URL_EMAIL_RESET")+"forget-password/confirm/{uid}/{token}", "USERNAME_RESET_CONFIRM_URL": "users/auth/users/username/reset/confirm/{uid}/{token}", "ACTIVATION_URL": "users/auth/users/activation/{uid}/{token}", "SEND_ACTIVATION_EMAIL": True, diff --git a/backend/users/managers.py b/backend/users/managers.py index 59031c5c..c4b3c6fc 100644 --- a/backend/users/managers.py +++ b/backend/users/managers.py @@ -9,7 +9,7 @@ def _create_user(self, email, password, **extra_fields): Create dummy users for invites. """ - email = self.normalize_email(email) + email = self.normalize_email(email.lower()) user = self.model(email=email, **extra_fields) user.set_password(password) @@ -20,7 +20,7 @@ def _create_user(self, email, password, **extra_fields): def create_user(self, email, password=None, **extra_fields): extra_fields.setdefault("is_staff", False) extra_fields.setdefault("is_superuser", False) - return self._create_user(email, password, **extra_fields) + return self._create_user(email.lower(), password, **extra_fields) def create_superuser(self, email, password, **extra_fields): extra_fields.setdefault("is_staff", True) @@ -31,4 +31,4 @@ def create_superuser(self, email, password, **extra_fields): if extra_fields.get("is_superuser") is not True: raise ValueError("Superuser must have is_superuser=True.") - return self._create_user(email, password, **extra_fields) + return self._create_user(email.lower(), password, **extra_fields) diff --git a/backend/users/views.py b/backend/users/views.py index 922b8f97..34960e86 100644 --- a/backend/users/views.py +++ b/backend/users/views.py @@ -168,6 +168,7 @@ def get( *args, **kwargs, ): + email_id = email_id.lower() interested_in = ", ".join(str(interested_in).title().split(" ")) onboarding_table_1 = onboarding_table.format( org_name=org_name, @@ -258,6 +259,7 @@ def invite_users(self, request): for email in emails: # Checking if the email is in valid format. + email = email.lower() if re.fullmatch(regex, email): try: user = User( @@ -397,7 +399,7 @@ def sign_up_user(self, request, pk=None): """ Users to sign up for the first time. """ - email = request.data.get("email") + email = request.data.get("email").lower() try: user = User.objects.get(email=email) except User.DoesNotExist: @@ -471,6 +473,7 @@ def re_invite(self, request): already_accepted_invite, ) = ([], [], [], []) for user_email in distinct_emails: + user_email = user_email.lower() if user_email in existing_emails_set: user = User.objects.get(email=user_email) if user.has_accepted_invite: @@ -726,7 +729,7 @@ def update_email(self, request): """ try: user = request.user - unverified_email = request.data.get("email") + unverified_email = request.data.get("email").lower() old_email_update_code = generate_random_string(10) new_email_verification_code = generate_random_string(10) From 4111d3fb954d31092c5b73665a70a71e3641e6f5 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 12 Sep 2024 12:23:02 +0530 Subject: [PATCH 08/80] added endpoints for set/get transcription translation and voiceover tasks --- backend/transcript/urls.py | 2 + backend/transcript/views.py | 142 ++++++++++++++++++++++++++++++++++ backend/translation/urls.py | 2 + backend/translation/views.py | 142 ++++++++++++++++++++++++++++++++++ backend/voiceover/urls.py | 2 + backend/voiceover/views.py | 144 ++++++++++++++++++++++++++++++++++- 6 files changed, 433 insertions(+), 1 deletion(-) diff --git a/backend/transcript/urls.py b/backend/transcript/urls.py index 88b25585..4c6f730a 100644 --- a/backend/transcript/urls.py +++ b/backend/transcript/urls.py @@ -12,6 +12,8 @@ name="generate_original_transcript", ), path("save/", views.save_transcription, name="save_transcript"), + path("get_transcription_status/", views.fetch_transcript_status, name="get_transcription_status"), + path("set_transcription_status/", views.update_transcript_status, name="set_transcription_status"), path( "save_full_transcript/", views.save_full_transcription, diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 7f21aa0f..691d0246 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -640,6 +640,148 @@ def get_transcript_id(task): ) return transcript_id +@swagger_auto_schema( + method="get", + manual_parameters=[ + openapi.Parameter( + "task_id", + openapi.IN_QUERY, + description=("An integer to pass the task id"), + type=openapi.TYPE_INTEGER, + required=True, + ), + ], + responses={ + 200: "Status has been fetched successfully", + 400: "Bad request", + 404: "No transcript found for given task", + }, +) +@api_view(["GET"]) +def fetch_transcript_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + task_id = request.query_params.get("task_id") + except KeyError: + return Response( + { + "message": "Missing required parameter - task_id" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + transcript = get_transcript_id(task) + if transcript is not None: + transcript_id = transcript.id + try: + transcript = Transcript.objects.get(pk=transcript_id) + return Response( + { + "message": "Status has been fetched successfully", + "task_id": task.id, + "transcript_id": transcript_id, + "status": transcript.status, + }, + status=status.HTTP_200_OK, + ) + except: + return Response( + {"message": "Transcript doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) + +@swagger_auto_schema( + method="post", + request_body=openapi.Schema( + type=openapi.TYPE_OBJECT, + required=["task_id", "trs_status"], + properties={ + "task_id": openapi.Schema( + type=openapi.TYPE_INTEGER, + description="An integer identifying the transcript instance", + ), + "trs_status": openapi.Schema( + type=openapi.TYPE_STRING, + description="Transcript task status to be set", + ) + }, + description="Post request body", + ), + responses={ + 200: "Status has been updated successfully", + 400: "Bad request", + 404: "No transcript found for given task", + }, +) +@api_view(["POST"]) +def update_transcript_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + # Get the required data from the POST body + task_id = request.data["task_id"] + trs_status = request.data["trs_status"] + except KeyError: + return Response( + { + "message": "Missing required parameters - task_id or trs_status" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + transcript = get_transcript_id(task) + if transcript is not None: + transcript_id = transcript.id + try: + transcript = Transcript.objects.get(pk=transcript_id) + if trs_status in ["TRANSCRIPTION_SELECT_SOURCE", "TRANSCRIPTION_EDITOR_ASSIGNED", "TRANSCRIPTION_EDIT_INPROGRESS", "TRANSCRIPTION_EDIT_COMPLETE", "TRANSCRIPTION_REVIEWER_ASSIGNED", "TRANSCRIPTION_REVIEW_INPROGRESS", "TRANSCRIPTION_REVIEW_COMPLETE"]: + transcript.status = trs_status + transcript.save() + return Response( + { + "message": "Status has been updated successfully", + }, + status=status.HTTP_200_OK, + ) + else: + return Response( + {"message": "Invalid Status"}, + status=status.HTTP_400_BAD_REQUEST, + ) + except: + return Response( + {"message": "Transcript doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) @swagger_auto_schema( method="get", diff --git a/backend/translation/urls.py b/backend/translation/urls.py index e50e93d9..1c32c1fd 100644 --- a/backend/translation/urls.py +++ b/backend/translation/urls.py @@ -11,6 +11,8 @@ name="retrieve_all_translations", ), path("save/", views.save_translation, name="save_translation"), + path("get_translation_status/", views.fetch_translation_status, name="get_translation_status"), + path("set_translation_status/", views.update_translation_status, name="set_translation_status"), path( "get_translation_supported_languages", views.get_translation_supported_languages, diff --git a/backend/translation/views.py b/backend/translation/views.py index 6570b1d9..cc1d8575 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -558,7 +558,149 @@ def get_translation_id(task): .first() ) return translation_id + +@swagger_auto_schema( + method="get", + manual_parameters=[ + openapi.Parameter( + "task_id", + openapi.IN_QUERY, + description=("An integer to pass the task id"), + type=openapi.TYPE_INTEGER, + required=True, + ), + ], + responses={ + 200: "Status has been fetched successfully", + 400: "Bad request", + 404: "No translation found for given task", + }, +) +@api_view(["GET"]) +def fetch_translation_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + task_id = request.query_params.get("task_id") + except KeyError: + return Response( + { + "message": "Missing required parameter - task_id" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + translation = get_translation_id(task) + if translation is not None: + translation_id = translation.id + try: + translation = Translation.objects.get(pk=translation_id) + return Response( + { + "message": "Status has been fetched successfully", + "task_id": task.id, + "translation_id": translation_id, + "status": translation.status, + }, + status=status.HTTP_200_OK, + ) + except: + return Response( + {"message": "Translation doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) + +@swagger_auto_schema( + method="post", + request_body=openapi.Schema( + type=openapi.TYPE_OBJECT, + required=["task_id", "trl_status"], + properties={ + "task_id": openapi.Schema( + type=openapi.TYPE_INTEGER, + description="An integer identifying the translation instance", + ), + "trl_status": openapi.Schema( + type=openapi.TYPE_STRING, + description="Translation task status to be set", + ) + }, + description="Post request body", + ), + responses={ + 200: "Status has been updated successfully", + 400: "Bad request", + 404: "No translation found for given task", + }, +) +@api_view(["POST"]) +def update_translation_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + # Get the required data from the POST body + task_id = request.data["task_id"] + trl_status = request.data["trl_status"] + except KeyError: + return Response( + { + "message": "Missing required parameters - task_id or trl_status" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + translation = get_translation_id(task) + if translation is not None: + translation_id = translation.id + try: + translation = Translation.objects.get(pk=translation_id) + if trl_status in ["TRANSLATION_SELECT_SOURCE", "TRANSLATION_EDITOR_ASSIGNED", "TRANSLATION_EDIT_INPROGRESS", "TRANSLATION_EDIT_COMPLETE", "TRANSLATION_REVIEWER_ASSIGNED", "TRANSLATION_REVIEW_INPROGRESS", "TRANSLATION_REVIEW_COMPLETE"]: + translation.status = trl_status + translation.save() + return Response( + { + "message": "Status has been updated successfully", + }, + status=status.HTTP_200_OK, + ) + else: + return Response( + {"message": "Invalid Status"}, + status=status.HTTP_400_BAD_REQUEST, + ) + except: + return Response( + {"message": "Translation doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) @swagger_auto_schema( method="get", diff --git a/backend/voiceover/urls.py b/backend/voiceover/urls.py index e64ed6ee..0cf95e70 100644 --- a/backend/voiceover/urls.py +++ b/backend/voiceover/urls.py @@ -10,6 +10,8 @@ ), path("get_translated_text/", views.get_translated_text, name="get_translated_text"), path("save/", views.save_voice_over, name="save_voice_over"), + path("get_voiceover_status/", views.fetch_voice_over_status, name="get_voice_over_staus"), + path("set_voiceover_status/", views.update_voice_over_status, name="set_voice_over_staus"), path( "get_voiceover_supported_languages", views.get_voiceover_supported_languages, diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index ae11a061..fe16db30 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -44,7 +44,7 @@ import uuid import regex from glossary.tmx.tmxservice import TMXService - +from organization.decorators import is_admin @api_view(["GET"]) def get_voice_over_export_types(request): @@ -727,7 +727,149 @@ def get_translated_text(request): {"message": "Translation failed"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) + +@swagger_auto_schema( + method="get", + manual_parameters=[ + openapi.Parameter( + "task_id", + openapi.IN_QUERY, + description=("An integer to pass the task id"), + type=openapi.TYPE_INTEGER, + required=True, + ), + ], + responses={ + 200: "Status has been fetched successfully", + 400: "Bad request", + 404: "No voice_over found for given task", + }, +) +@api_view(["GET"]) +def fetch_voice_over_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + task_id = request.query_params.get("task_id") + except KeyError: + return Response( + { + "message": "Missing required parameter - task_id" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + voice_over = get_voice_over_id(task) + if voice_over is not None: + voice_over_id = voice_over.id + try: + voice_over = VoiceOver.objects.get(pk=voice_over_id) + return Response( + { + "message": "Status has been fetched successfully", + "task_id": task.id, + "voiceover_id": voice_over_id, + "status": voice_over.status, + }, + status=status.HTTP_200_OK, + ) + except: + return Response( + {"message": "VoiceOver doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) + +@swagger_auto_schema( + method="post", + request_body=openapi.Schema( + type=openapi.TYPE_OBJECT, + required=["task_id", "vo_status"], + properties={ + "task_id": openapi.Schema( + type=openapi.TYPE_INTEGER, + description="An integer identifying the voice_over instance", + ), + "vo_status": openapi.Schema( + type=openapi.TYPE_STRING, + description="Voiceover task status to be set", + ) + }, + description="Post request body", + ), + responses={ + 200: "Status has been updated successfully", + 400: "Bad request", + 404: "No voice_over found for given task", + }, +) +@api_view(["POST"]) +def update_voice_over_status(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + # Get the required data from the POST body + task_id = request.data["task_id"] + vo_status = request.data["vo_status"] + except KeyError: + return Response( + { + "message": "Missing required parameters - task_id or vo_status" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + if not task.is_active: + return Response( + {"message": "This task is not active yet."}, + status=status.HTTP_400_BAD_REQUEST, + ) + voice_over = get_voice_over_id(task) + if voice_over is not None: + voice_over_id = voice_over.id + try: + voice_over = VoiceOver.objects.get(pk=voice_over_id) + if vo_status in ["VOICEOVER_SELECT_SOURCE", "VOICEOVER_EDITOR_ASSIGNED", "VOICEOVER_EDIT_INPROGRESS", "VOICEOVER_EDIT_COMPLETE", "VOICEOVER_REVIEWER_ASSIGNED", "VOICEOVER_REVIEW_INPROGRESS", "VOICEOVER_REVIEW_COMPLETE"]: + voice_over.status = vo_status + voice_over.save() + return Response( + { + "message": "Status has been updated successfully", + }, + status=status.HTTP_200_OK, + ) + else: + return Response( + {"message": "Invalid Status"}, + status=status.HTTP_400_BAD_REQUEST, + ) + except: + return Response( + {"message": "VoiceOver doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) @swagger_auto_schema( method="post", From d06c9a1c10c46fdbf0bd41359305e1eaa2c09cbf Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 12 Sep 2024 16:38:28 +0530 Subject: [PATCH 09/80] changes for password reset email link --- backend/backend/settings.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/backend/settings.py b/backend/backend/settings.py index a5fe2f6c..c7f625ce 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -94,10 +94,10 @@ DOMAIN = os.getenv("DOMAIN") SITE_NAME = os.getenv("DOMAIN") -PROTOCOL = "https" +DEFAULT_HTTP_PROTOCOL = 'https' DJOSER = { - "PASSWORD_RESET_CONFIRM_URL": os.getenv("FRONTEND_URL_EMAIL_RESET")+"forget-password/confirm/{uid}/{token}", + "PASSWORD_RESET_CONFIRM_URL": "forget-password/confirm/{uid}/{token}", "USERNAME_RESET_CONFIRM_URL": "users/auth/users/username/reset/confirm/{uid}/{token}", "ACTIVATION_URL": "users/auth/users/activation/{uid}/{token}", "SEND_ACTIVATION_EMAIL": True, @@ -125,6 +125,7 @@ CSRF_TRUSTED_ORIGINS = [ "http://localhost:*", # for localhost (Developlemt) + "https://*.ai4bharat.org", ] CUSTOM_CSRF_TRUSTED_ORIGINS = os.getenv("CORS_TRUSTED_ORIGINS", "") if CUSTOM_CSRF_TRUSTED_ORIGINS: From 4d3de165edb3d958b61846be5e9868632761e415 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 13 Sep 2024 13:43:30 +0530 Subject: [PATCH 10/80] add project title to django admin view --- backend/project/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/project/admin.py b/backend/project/admin.py index 7c28b90b..f52d3639 100644 --- a/backend/project/admin.py +++ b/backend/project/admin.py @@ -9,6 +9,7 @@ class ProjectAdmin(admin.ModelAdmin): list_display = ( "id", + "title", "organization_id", "default_task_types", "default_target_languages", From 34dc0bf448db9197e415dddb087376ff2eae55e0 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 16 Sep 2024 13:48:27 +0530 Subject: [PATCH 11/80] fixed auto save failing when page changes for transcription task --- backend/transcript/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 691d0246..ac3dc710 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1545,9 +1545,9 @@ def modify_payload(offset, limit, payload, start_offset, end_offset, transcript) ), # Generate paraphrased text if paraphrase=true }, ) - last_valid_end_time = transcript.payload["payload"][len(payload["payload"])][ - "end_time" - ] + # last_valid_end_time = transcript.payload["payload"][len(payload["payload"])][ + # "end_time" + # ] offset_to_check = start_offset + len(payload["payload"]) last_valid_start_time = transcript.payload["payload"][offset_to_check - 1][ "start_time" From 382289891f846f46ec793dc60818bef6d88282f1 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Sep 2024 11:32:04 +0530 Subject: [PATCH 12/80] add error message for 0 duration --- backend/voiceover/views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index fe16db30..6cae3868 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1136,11 +1136,16 @@ def save_voice_over(request): text = voice_over_payload["text"] if text == "" or len(text) == 0: return Response( - {"message": "Text can't be empty."}, + {"message": "Text can't be empty for segment "+str(index+1)}, status=status.HTTP_400_BAD_REQUEST, ) original_duration = get_original_duration(start_time, end_time) + if original_duration < 0.5: + return Response( + {"message": "Duration can't be 0 for segment "+str(index+1)}, + status=status.HTTP_400_BAD_REQUEST, + ) if ( voice_over.voice_over_type == "MACHINE_GENERATED" From 252e18020f4fa8e70386e27d0464effe0a823948 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Sep 2024 12:15:06 +0530 Subject: [PATCH 13/80] fix transcription taask complete bug --- backend/transcript/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index ac3dc710..9bc1f44b 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -2021,7 +2021,7 @@ def save_transcription(request): ) for item in transcript_obj.payload["payload"]: item['verbatim_text'] = item.pop('text') - item['text'] = item['paraphrased_text'] + item['text'] = item['paraphrased_text'] if item['paraphrased_text'] is not None else item ['verbatim_text'] transcript_obj.save() task.status = "COMPLETE" task.save() From cc3af45ed6d8f598982c31c03633827b23fb5678 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Sep 2024 12:16:25 +0530 Subject: [PATCH 14/80] fix transcription taask complete bug --- backend/transcript/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 9bc1f44b..fcdbbe7a 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -2021,7 +2021,7 @@ def save_transcription(request): ) for item in transcript_obj.payload["payload"]: item['verbatim_text'] = item.pop('text') - item['text'] = item['paraphrased_text'] if item['paraphrased_text'] is not None else item ['verbatim_text'] + item['text'] = item['paraphrased_text'] if item['paraphrased_text'] is not None else item['verbatim_text'] transcript_obj.save() task.status = "COMPLETE" task.save() From 32bcca88850a5a54e7f06ecbe151a512aa3a4cc0 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Sep 2024 12:39:38 +0530 Subject: [PATCH 15/80] minor fix for submitting transcription --- backend/transcript/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index fcdbbe7a..255cd751 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1993,6 +1993,9 @@ def save_transcription(request): if task.status == "INPROGRESS": task.status = "COMPLETE" task.save() + if task.status == "SELECTED_SOURCE": + task.status = "COMPLETE" + task.save() return Response( { "message": "Final Edited Transcript already submitted." From 0252045e792d89afe066edcf60a871e9d8e1d049 Mon Sep 17 00:00:00 2001 From: Kartik Virendra Rajput <88619994+kartikvirendrar@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:46:16 +0530 Subject: [PATCH 16/80] change duration 0 error message to appear for duration < 0.1 --- backend/voiceover/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 6cae3868..98bb5ea1 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1141,7 +1141,7 @@ def save_voice_over(request): ) original_duration = get_original_duration(start_time, end_time) - if original_duration < 0.5: + if original_duration < 0.1: return Response( {"message": "Duration can't be 0 for segment "+str(index+1)}, status=status.HTTP_400_BAD_REQUEST, From ab6da96512953d4dd7a4d911c9b971bccd0bdd6d Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 20 Sep 2024 11:51:37 +0530 Subject: [PATCH 17/80] fix minor bug in paraphrasing --- backend/transcript/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 255cd751..1aa6025e 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1350,7 +1350,10 @@ def change_active_status_of_next_tasks(task, transcript_obj): # Helper function to call the paraphrasing API def paraphrase_text(text): # Set API configuration - text = get_model_output(user_prompt=text) + try: + text = get_model_output(user_prompt=text) + except: + True return text From a055285efc9b179e283b0733d1d8c29fdb9fbdbe Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Sat, 21 Sep 2024 10:33:11 +0530 Subject: [PATCH 18/80] fix for bookmark segment --- backend/transcript/views.py | 4 +--- backend/translation/views.py | 2 +- backend/voiceover/views.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 1aa6025e..3a5ffa97 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1884,9 +1884,7 @@ def save_transcription(request): transcript_id = transcript.id bookmarked_segment = request.data.get("bookmark", None) user = request.user - print(bookmarked_segment) - if bookmarked_segment: - print("Saving History") + if bookmarked_segment is not None: user.user_history = { "task_id": task_id, "offset": offset, diff --git a/backend/translation/views.py b/backend/translation/views.py index cc1d8575..1edd6838 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -1673,7 +1673,7 @@ def save_translation(request): ) bookmarked_segment = request.data.get("bookmark", None) user = request.user - if bookmarked_segment: + if bookmarked_segment is not None: user.user_history = { "task_id": task_id, "offset": offset, diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 6cae3868..a0ba09d5 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -948,7 +948,7 @@ def save_voice_over(request): bookmarked_segment = request.data.get("bookmark", None) user = request.user - if bookmarked_segment: + if bookmarked_segment is not None: user.user_history = { "task_id": task_id, "offset": offset, From e15c2d027fdb17a17615a35223260bae2ba053b8 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 24 Sep 2024 14:05:56 +0530 Subject: [PATCH 19/80] add endpoint to reopen transcription task --- backend/transcript/urls.py | 1 + backend/transcript/views.py | 64 +++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/backend/transcript/urls.py b/backend/transcript/urls.py index 4c6f730a..28f4c1c4 100644 --- a/backend/transcript/urls.py +++ b/backend/transcript/urls.py @@ -12,6 +12,7 @@ name="generate_original_transcript", ), path("save/", views.save_transcription, name="save_transcript"), + path("reopen_completed_transcription_task/", views.reopen_completed_transcription_task, name="reopen_completed_transcription_task"), path("get_transcription_status/", views.fetch_transcript_status, name="get_transcription_status"), path("set_transcription_status/", views.update_transcript_status, name="set_transcription_status"), path( diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 3a5ffa97..900ebb94 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -640,6 +640,66 @@ def get_transcript_id(task): ) return transcript_id +@swagger_auto_schema( + method="get", + manual_parameters=[ + openapi.Parameter( + "task_id", + openapi.IN_QUERY, + description=("An integer to pass the task id"), + type=openapi.TYPE_INTEGER, + required=True, + ), + ], + responses={ + 200: "Status has been changed successfully", + 400: "Bad request", + 404: "No transcript found for given task", + }, +) +@api_view(["GET"]) +def reopen_completed_transcription_task(request): + if not request.user.is_authenticated: + return Response({"message":"You do not have enough permissions to access this view!"}, status=401) + try: + task_id = request.query_params.get("task_id") + except KeyError: + return Response( + { + "message": "Missing required parameter - task_id" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + task = Task.objects.get(pk=task_id) + except Task.DoesNotExist: + return Response( + {"message": "Task doesn't exist."}, + status=status.HTTP_404_NOT_FOUND, + ) + + transcript = get_transcript_id(task) + if transcript is not None: + transcript_id = transcript.id + try: + transcript = Transcript.objects.get(pk=transcript_id) + transcript.delete() + task.status = "INPROGRESS" + task.save() + return Response( + { + "message": "Status has been changed successfully" + }, + status=status.HTTP_200_OK, + ) + except: + return Response( + {"message": "Transcript doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + @swagger_auto_schema( method="get", manual_parameters=[ @@ -2024,7 +2084,7 @@ def save_transcription(request): transcript_obj, ) for item in transcript_obj.payload["payload"]: - item['verbatim_text'] = item.pop('text') + item['verbatim_text'] = item['text'] item['text'] = item['paraphrased_text'] if item['paraphrased_text'] is not None else item['verbatim_text'] transcript_obj.save() task.status = "COMPLETE" @@ -2138,7 +2198,7 @@ def save_transcription(request): transcript_obj, ) for item in transcript_obj.payload["payload"]: - item['verbatim_text'] = item.pop('text') + item['verbatim_text'] = item['text'] item['text'] = item['paraphrased_text'] transcript_obj.save() task.status = "COMPLETE" From db894ff27ff3694b4f70bfe7b9aaa9317caba514 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 24 Sep 2024 14:13:16 +0530 Subject: [PATCH 20/80] fixed minor bug in completing transcription task --- backend/transcript/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 900ebb94..5d4b56d5 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1967,7 +1967,7 @@ def save_transcription(request): {"message": "Invalid Transcript."}, status=status.HTTP_400_BAD_REQUEST ) # Check if the transcript has a user - if task.user != request.user: + if task.user == request.user: return Response( {"message": "You are not allowed to update this transcript."}, status=status.HTTP_400_BAD_REQUEST, @@ -2057,6 +2057,9 @@ def save_transcription(request): if task.status == "SELECTED_SOURCE": task.status = "COMPLETE" task.save() + if task.status == "PARAPHRASE": + task.status = "COMPLETE" + task.save() return Response( { "message": "Final Edited Transcript already submitted." From ea82c61ff114750f065c5f14fc6c9b9292ad80cc Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 24 Sep 2024 14:14:32 +0530 Subject: [PATCH 21/80] fixed minor bug in completing transcription task --- backend/transcript/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 5d4b56d5..a9aa6e1a 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1967,7 +1967,7 @@ def save_transcription(request): {"message": "Invalid Transcript."}, status=status.HTTP_400_BAD_REQUEST ) # Check if the transcript has a user - if task.user == request.user: + if task.user != request.user: return Response( {"message": "You are not allowed to update this transcript."}, status=status.HTTP_400_BAD_REQUEST, From f4b06719486bb61bb78a2e0114a82fcf25f337cc Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 2 Oct 2024 12:35:18 +0530 Subject: [PATCH 22/80] added regenerate for VOTR --- backend/organization/views.py | 3 +++ backend/project/views.py | 3 +++ backend/task/views.py | 8 +++++++- backend/transcript/views.py | 2 -- backend/translation/views.py | 17 ++++++++++++++++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/backend/organization/views.py b/backend/organization/views.py index 0cab44a5..64ccb5d6 100644 --- a/backend/organization/views.py +++ b/backend/organization/views.py @@ -496,6 +496,9 @@ def list_org_tasks(self, request, pk=None, *args, **kwargs): task["updated_at"] ).replace(tzinfo=None): buttons["Reopen"] = False + if "TRANSLATION_VOICEOVER" in task["task_type"]: + if task["status"] in ["SELECTED_SOURCE", "FAILED"] and task["is_active"] is False: + buttons["Regenerate"] = True if task["status"] == "POST_PROCESS": buttons["Update"] = True if task["status"] == "FAILED": diff --git a/backend/project/views.py b/backend/project/views.py index 8eb00844..d6d29d9a 100644 --- a/backend/project/views.py +++ b/backend/project/views.py @@ -861,6 +861,9 @@ def list_project_tasks(self, request, pk=None, *args, **kwargs): data["updated_at"] ).replace(tzinfo=None): buttons["Reopen"] = False + if "TRANSLATION_VOICEOVER" in data["task_type"]: + if data["status"] in ["SELECTED_SOURCE", "FAILED"] and data["is_active"] is False: + buttons["Regenerate"] = True if data["status"] == "POST_PROCESS": buttons["Update"] = True if data["status"] == "FAILED": diff --git a/backend/task/views.py b/backend/task/views.py index f2ca340b..84fefd8e 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -87,7 +87,7 @@ from rest_framework.decorators import parser_classes from rest_framework.parsers import MultiPartParser, FormParser import regex - +from translation.views import regenerate_translation_voiceover def get_export_translation(request, task_id, export_type): new_request = HttpRequest() @@ -3392,6 +3392,12 @@ def regenerate_response(self, request, pk, *args, **kwargs): elif task.task_type == "VOICEOVER_EDIT": celery_tts_call.delay(task_id=task.id) api = "TTS" + elif task.task_type == "TRANSLATION_VOICEOVER_EDIT": + if regenerate_translation_voiceover(task.id) is False: + return Response( + {"message": "Transcription task is not complete yet"}, status=status.HTTP_400_BAD_REQUEST + ) + api = "NMT-TTS" else: return Response( {"message": "Invalid task"}, status=status.HTTP_400_BAD_REQUEST diff --git a/backend/transcript/views.py b/backend/transcript/views.py index a9aa6e1a..94ea0ec9 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -1362,8 +1362,6 @@ def change_active_status_of_next_tasks(task, transcript_obj): translation.save() if source_type == None or source_type == "MACHINE_GENERATED": source_type = "MACHINE_GENERATED" - translation.transcript = transcript_obj - translation.save() celery_nmt_tts_call.delay(task_id=translation.task.id) else: payloads = generate_translation_payload( diff --git a/backend/translation/views.py b/backend/translation/views.py index 1edd6838..8013e71b 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -69,7 +69,8 @@ from transcript.utils.timestamp import * from django.core.mail import EmailMultiAlternatives from django.conf import settings - +from transcript.views import get_transcript_id +from task.tasks import celery_nmt_tts_call @api_view(["GET"]) def get_translation_export_types(request): @@ -2335,3 +2336,17 @@ def get_translation_report(request): res.append(temp_data) return Response(res, status=status.HTTP_200_OK) + +def regenerate_translation_voiceover(task_id): + task_obj = Task.objects.get(pk=task_id) + video = Video.objects.filter(id=task_obj.video_id).first() + transcription_task = Task.objects.filter(video=video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() + if transcription_task is None: + return False + transcript = get_transcript_id(transcription_task) + transcript_obj = Transcript.objects.get(pk=transcript.id) + translation = Translation.objects.filter(task=task_obj).first() + translation.transcript = transcript_obj + translation.save() + celery_nmt_tts_call.delay(task_id) + return True \ No newline at end of file From 6bb0461b8456e9cf704c1065b9db3467fe803b51 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 4 Oct 2024 16:20:30 +0530 Subject: [PATCH 23/80] fixes for 0 duration error --- backend/voiceover/utils.py | 8 ++++++++ backend/voiceover/views.py | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 2de2e17c..13ae1b61 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -1157,6 +1157,14 @@ def check_audio_completion(voice_over_obj): "message": "There is no audio present in this card.", } ) + if (get_original_duration(voice_over_obj.payload["payload"][str(index)]["start_time"], voice_over_obj.payload["payload"][str(index)]["end_time"]) < 0.1): + missing_cards.append( + { + "card_number": index + 1, + "message": "Duration is 0 for this card.", + } + ) + return missing_cards diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index a0ba09d5..07d92b73 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1141,11 +1141,6 @@ def save_voice_over(request): ) original_duration = get_original_duration(start_time, end_time) - if original_duration < 0.5: - return Response( - {"message": "Duration can't be 0 for segment "+str(index+1)}, - status=status.HTTP_400_BAD_REQUEST, - ) if ( voice_over.voice_over_type == "MACHINE_GENERATED" From 11d8a070b247368db7345ffa7ce24e92b00d5966 Mon Sep 17 00:00:00 2001 From: Kartik Virendra Rajput <88619994+kartikvirendrar@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:04:20 +0530 Subject: [PATCH 24/80] add Nepali to transcription languages list --- backend/transcript/metadata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/transcript/metadata.py b/backend/transcript/metadata.py index 0c308f5d..b424458d 100644 --- a/backend/transcript/metadata.py +++ b/backend/transcript/metadata.py @@ -13,6 +13,7 @@ ("te", "Telugu"), ("sa", "Sanskrit"), ("ur", "Urdu"), + ("ne", "Nepali"), ] TRANSCRIPTION_SUPPORTED_LANGUAGES = { @@ -29,4 +30,5 @@ "Tamil": "ta", "Telugu": "te", "Urdu": "ur", + "Nepali": "ne", } From 9896d0b559e9cd525ef74ab52775244b67fecba7 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 7 Oct 2024 12:38:48 +0530 Subject: [PATCH 25/80] added votr active task export transcript and translation --- backend/transcript/views.py | 35 ++++++++++++++++++++++++++++++----- backend/translation/views.py | 2 -- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 94ea0ec9..561941f4 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -77,7 +77,7 @@ from .utils.timestamp import * import openai from utils.llm_api import get_model_output - +from voiceover.models import VoiceOver @api_view(["GET"]) def get_transcript_export_types(request): @@ -161,10 +161,35 @@ def export_transcript(request): transcript = get_transcript_id(task) if transcript is None: - return Response( - {"message": "Transcript not found."}, - status=status.HTTP_404_NOT_FOUND, - ) + try: + if task.task_type == "TRANSLATION_VOICEOVER_EDIT" and task.status != "COMPLETE": + voice_over_obj = VoiceOver.objects.filter(task=task).first() + transcript = voice_over_obj.translation.transcript + updated_payload = [] + index = 0 + for segment in voice_over_obj.payload["payload"].values(): + start_time = datetime.datetime.strptime( + segment["start_time"], "%H:%M:%S.%f" + ) + end_time = datetime.datetime.strptime(segment["end_time"], "%H:%M:%S.%f") + unix_start_time = datetime.datetime.timestamp(start_time) + unix_end_time = datetime.datetime.timestamp(end_time) + + updated_segment = { + "start_time": segment["start_time"], + "end_time": segment["end_time"], + "text": segment["transcription_text"], + "speaker_id": "", + "unix_start_time": unix_start_time, + "unix_end_time": unix_end_time, + } + updated_payload.append(updated_segment) + transcript.payload["payload"] = updated_payload + except: + return Response( + {"message": "Transcript not found."}, + status=status.HTTP_404_NOT_FOUND, + ) if with_speaker_info: speaker_info = transcript.video.multiple_speaker diff --git a/backend/translation/views.py b/backend/translation/views.py index 8013e71b..8686c7d2 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -163,8 +163,6 @@ def export_translation(request): end_time = datetime.datetime.strptime(segment["end_time"], "%H:%M:%S.%f") unix_start_time = datetime.datetime.timestamp(start_time) unix_end_time = datetime.datetime.timestamp(end_time) - target_text = segment["text"] - target_text = segment["transcription_text"] updated_segment = { "start_time": segment["start_time"], From 751c3d75a1449d78266fb8c799930baea39f787c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 8 Oct 2024 10:48:45 +0530 Subject: [PATCH 26/80] minor fix for bulk video upload --- backend/video/views.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/video/views.py b/backend/video/views.py index 81885620..b2d2c0e6 100644 --- a/backend/video/views.py +++ b/backend/video/views.py @@ -1024,6 +1024,27 @@ def upload_csv_data(request): else: valid_row["assignee"] = User.objects.get(email=row["Assignee"].strip()).id + format = "%d-%m-%Y" + input_eta = datetime.datetime.strptime(row["ETA"], format) + curr_date = datetime.datetime.now().date() + if bool(input_eta) == False: + errors.append( + { + "row_no": f"Row {row_num}", + "message": f"Invalid ETA Format, expected format is dd-mm-yyyy: received{row['ETA']}", + } + ) + elif input_eta.date() < curr_date: + errors.append( + { + "row_no": f"Row {row_num}", + "message": f"ETA can't be less than current Date: received{row['ETA']}", + } + ) + + else: + valid_row["ETA"] = input_eta.strftime("%Y-%m-%dT18:29:00.000Z") + valid_row["video_description"] = row["Video Description"] valid_row["task_description"] = row["Task Description"] video = Video.objects.filter(url=row["Youtube URL"].strip()).first() From f6778b17ee44fe42aed6da1782e1761bd6b59bb8 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 8 Oct 2024 20:23:14 +0530 Subject: [PATCH 27/80] minor fix for 0 duration error --- backend/voiceover/utils.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 13ae1b61..d5289700 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -1137,6 +1137,13 @@ def check_audio_completion(voice_over_obj): for index, payload in enumerate(voice_over_obj.translation.payload["payload"]): if str(index) in voice_over_obj.payload["payload"].keys(): + if (get_original_duration(voice_over_obj.payload["payload"][str(index)]["start_time"], voice_over_obj.payload["payload"][str(index)]["end_time"]) < 0.1): + missing_cards.append( + { + "card_number": index + 1, + "message": "Duration is 0 for this card.", + } + ) if ( "audio" in voice_over_obj.payload["payload"][str(index)].keys() and type(voice_over_obj.payload["payload"][str(index)]["audio"]) == dict @@ -1157,13 +1164,6 @@ def check_audio_completion(voice_over_obj): "message": "There is no audio present in this card.", } ) - if (get_original_duration(voice_over_obj.payload["payload"][str(index)]["start_time"], voice_over_obj.payload["payload"][str(index)]["end_time"]) < 0.1): - missing_cards.append( - { - "card_number": index + 1, - "message": "Duration is 0 for this card.", - } - ) return missing_cards From 97a77192c71a31b499b828ec24f4084625df79d7 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 10 Oct 2024 11:26:43 +0530 Subject: [PATCH 28/80] minor changes for xlit endpoint --- backend/backend/urls.py | 2 +- backend/video/urls.py | 2 +- backend/video/views.py | 24 ++++++++---------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/backend/backend/urls.py b/backend/backend/urls.py index 107481ed..7db6798b 100644 --- a/backend/backend/urls.py +++ b/backend/backend/urls.py @@ -74,7 +74,7 @@ def get_schema(self, request=None, public=False): path("voiceover/", include("voiceover.urls")), path("youtube/", include("youtube.urls")), path( - "api/generic/transliteration///", + "xlit-api/generic/transliteration//", TransliterationAPIView.as_view(), name="transliteration-api", ), diff --git a/backend/video/urls.py b/backend/video/urls.py index 32789a86..c9e82354 100644 --- a/backend/video/urls.py +++ b/backend/video/urls.py @@ -6,7 +6,7 @@ urlpatterns = [ path("", views.get_video, name="get_video"), path( - "api/generic/transliteration///", + "xlit-api/generic/transliteration//", TransliterationAPIView.as_view(), name="transliteration-api", ), diff --git a/backend/video/views.py b/backend/video/views.py index b2d2c0e6..69c80a59 100644 --- a/backend/video/views.py +++ b/backend/video/views.py @@ -37,6 +37,7 @@ from collections import Counter from rest_framework.views import APIView import config +from rest_framework.permissions import IsAuthenticated accepted_languages = [ "as", @@ -96,25 +97,16 @@ class TransliterationAPIView(APIView): + permission_classes = [IsAuthenticated] + def get(self, request, target_language, data, *args, **kwargs): - json_data = { - "input": [{"source": data}], - "config": { - "language": { - "sourceLanguage": "en", - "targetLanguage": target_language, - }, - "isSentence": False, - "numSuggestions": 5, - }, - } - logging.info("Calling Transliteration API") - response_transliteration = requests.post( - config.transliteration_url, - headers={"authorization": config.dhruva_key}, - json=json_data, + response_transliteration = requests.get( + os.getenv("TRANSLITERATION_URL") + target_language + "/" + data, + # headers={"Authorization": "Bearer " + os.getenv("TRANSLITERATION_KEY")}, ) + print(response_transliteration) + transliteration_output = response_transliteration.json() return Response(transliteration_output, status=status.HTTP_200_OK) From 24ac72e1951b85e980681ebbba5c3a36188c5226 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 10 Oct 2024 11:27:08 +0530 Subject: [PATCH 29/80] minor changes for xlit endpoint --- backend/video/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/video/views.py b/backend/video/views.py index 69c80a59..8cbeaa1c 100644 --- a/backend/video/views.py +++ b/backend/video/views.py @@ -102,7 +102,7 @@ class TransliterationAPIView(APIView): def get(self, request, target_language, data, *args, **kwargs): response_transliteration = requests.get( os.getenv("TRANSLITERATION_URL") + target_language + "/" + data, - # headers={"Authorization": "Bearer " + os.getenv("TRANSLITERATION_KEY")}, + headers={"Authorization": "Bearer " + os.getenv("TRANSLITERATION_KEY")}, ) print(response_transliteration) From f8f450a9c123e20a9ba99b324b38880b8f01ad4a Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 11 Oct 2024 16:09:08 +0530 Subject: [PATCH 30/80] add asr service id for nepali language --- backend/config.py | 1 + backend/transcript/utils/asr.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/backend/config.py b/backend/config.py index fda9127f..28567d08 100644 --- a/backend/config.py +++ b/backend/config.py @@ -6,6 +6,7 @@ english_asr_url = os.getenv("ENGLISH_ASR_API_URL") indic_asr_url = os.getenv("INDIC_ASR_API_URL") service_id_hindi = os.getenv("SERVICE_ID_HINDI") +service_id_nepali = os.getenv("SERVICE_ID_NEPALI") service_id_indo_aryan = os.getenv("SERVICE_ID_INDO_ARYAN") service_id_dravidian = os.getenv("SERVICE_ID_DRAVIDIAN") misc_tts_url = os.getenv("MISC_TTS_API_URL") diff --git a/backend/transcript/utils/asr.py b/backend/transcript/utils/asr.py index 2bb77d85..aa92bc95 100644 --- a/backend/transcript/utils/asr.py +++ b/backend/transcript/utils/asr.py @@ -8,6 +8,7 @@ indic_asr_url, dhruva_key, service_id_hindi, + service_id_nepali, service_id_indo_aryan, service_id_dravidian, ) @@ -51,6 +52,8 @@ def make_asr_api_call(url, lang, vad_level=3, chunk_size=10): service_id = service_id_indo_aryan elif lang in ["kn", "ml", "ta", "te"]: service_id = service_id_dravidian + elif lang in ["ne"]: + service_id = service_id_nepali else: return None From 1f1849d47c9c2441b628729d31f6dfefcb23285c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 15 Oct 2024 12:24:03 +0530 Subject: [PATCH 31/80] minor changes in task_queues api --- backend/task/views.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/backend/task/views.py b/backend/task/views.py index 84fefd8e..22f81738 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -3193,6 +3193,8 @@ def inspect_queue(self, request): ) elif elem["name"] == "task.tasks.celery_nmt_call": task_obj["task_id"] = eval(elem["kwargs"])["task_id"] + elif elem["name"] == "task.tasks.celery_nmt_tts_call": + task_obj["task_id"] = eval(elem["kwargs"])["task_id"] else: task_obj["task_id"] = "" @@ -3230,11 +3232,13 @@ def inspect_queue(self, request): ) else: if queue == "nmt": - queue_type = "celery@nmt_worker" + queue_type = "task.tasks.celery_nmt_call" elif queue == "tts": - queue_type = "celery@asr_tts_worker" + queue_type = "task.tasks.celery_tts_call" + elif queue == "nmt_tts": + queue_type = "task.tasks.celery_nmt_tts_call" else: - queue_type = "celery@asr_tts_worker" + queue_type = "task.tasks.celery_asr_call" try: task_list = [] @@ -3242,7 +3246,7 @@ def inspect_queue(self, request): params = { "state": "STARTED", "sort_by": "received", - "workername": queue_type, + "name": queue_type, } if flower_username and flower_password: res = requests.get( From cacf50310e0c6e615196dea878c6dc6fafa3ff26 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 15 Oct 2024 13:14:56 +0530 Subject: [PATCH 32/80] minor changes in task_queues api --- backend/task/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/task/views.py b/backend/task/views.py index 22f81738..b6135a87 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -3194,7 +3194,7 @@ def inspect_queue(self, request): elif elem["name"] == "task.tasks.celery_nmt_call": task_obj["task_id"] = eval(elem["kwargs"])["task_id"] elif elem["name"] == "task.tasks.celery_nmt_tts_call": - task_obj["task_id"] = eval(elem["kwargs"])["task_id"] + task_obj["task_id"] = eval(elem["kwargs"])["task_id"] or eval(elem["args"])[0] else: task_obj["task_id"] = "" From bcd9d8126f85e33da38eee46665ab2b9286b9787 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 15 Oct 2024 22:26:19 +0530 Subject: [PATCH 33/80] minor fixes in task queue status --- backend/task/views.py | 66 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/backend/task/views.py b/backend/task/views.py index b6135a87..b98fc0e1 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -3194,7 +3194,14 @@ def inspect_queue(self, request): elif elem["name"] == "task.tasks.celery_nmt_call": task_obj["task_id"] = eval(elem["kwargs"])["task_id"] elif elem["name"] == "task.tasks.celery_nmt_tts_call": - task_obj["task_id"] = eval(elem["kwargs"])["task_id"] or eval(elem["args"])[0] + try: + task_obj["task_id"] = eval(elem["kwargs"])["task_id"] + except: + task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) + elif elem["name"] == "voiceover.tasks.celery_integration": + task_obj["task_id"] = eval(elem["args"].split(",")[2]) + elif elem["name"] == "voiceover.tasks.export_voiceover_async": + task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) else: task_obj["task_id"] = "" @@ -3231,22 +3238,18 @@ def inspect_queue(self, request): status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) else: - if queue == "nmt": - queue_type = "task.tasks.celery_nmt_call" - elif queue == "tts": - queue_type = "task.tasks.celery_tts_call" - elif queue == "nmt_tts": - queue_type = "task.tasks.celery_nmt_tts_call" + if queue == "nmt" or queue == "nmt_tts": + queue_type = "celery@nmt_worker" else: - queue_type = "task.tasks.celery_asr_call" + queue_type = "celery@asr_tts_worker" try: task_list = [] + status_list = [] url = f"{flower_url}/api/tasks" params = { - "state": "STARTED", - "sort_by": "received", - "name": queue_type, + "sort_by": "-received", + "workername": queue_type, } if flower_username and flower_password: res = requests.get( @@ -3259,42 +3262,27 @@ def inspect_queue(self, request): for elem in task_data: if queue == "asr" and elem["name"] == "task.tasks.celery_asr_call": task_list.append(eval(elem["kwargs"])["task_id"]) + status_list.append(elem["state"]) elif ( queue == "tts" and elem["name"] == "task.tasks.celery_tts_call" ): # task_list.append(eval(elem["kwargs"])["task_id"]) task_list.append(eval(elem["args"].split(",")[0].split("(")[1])) + status_list.append(elem["state"]) elif ( queue == "nmt" and elem["name"] == "task.tasks.celery_nmt_call" ): task_list.append(eval(elem["kwargs"])["task_id"]) - else: - pass - params = { - "state": "RECEIVED", - "sort_by": "received", - "workername": queue_type, - } - if flower_username and flower_password: - res = requests.get( - url, params=params, auth=(flower_username, flower_password) - ) - else: - res = requests.get(url, params=params) - data = res.json() - task_data = list(data.values()) - for elem in task_data: - if queue == "asr" and elem["name"] == "task.tasks.celery_asr_call": - task_list.append(eval(elem["kwargs"])["task_id"]) - elif ( - queue == "tts" and elem["name"] == "task.tasks.celery_tts_call" - ): - # task_list.append(eval(elem["kwargs"])["task_id"]) - task_list.append(eval(elem["args"].split(",")[0].split("(")[1])) + status_list.append(elem["state"]) elif ( - queue == "nmt" and elem["name"] == "task.tasks.celery_nmt_call" + queue == "nmt_tts" and elem["name"] == "task.tasks.celery_nmt_tts_call" ): - task_list.append(eval(elem["kwargs"])["task_id"]) + try: + task_list.append(eval(elem["kwargs"])["task_id"]) + status_list.append(elem["state"]) + except: + task_list.append(eval(elem["args"].split(",")[0].split("(")[1])) + status_list.append(elem["state"]) else: pass if task_list: @@ -3318,8 +3306,12 @@ def inspect_queue(self, request): "video_duration": str(elem["video__duration"]), } i = task_list.index(elem["id"]) + task_dict["status"] = status_list[i] task_list[i] = task_dict - + for i in task_list: + if type(i) == int: + j = task_list.index(i) + task_list[j] = {"task_id": i, "status": "Not Found"} return Response( {"message": "successful", "data": task_list}, status=status.HTTP_200_OK, From 034ec9630b2ee1d26140938700103dc0891d0a0a Mon Sep 17 00:00:00 2001 From: Ishvinder Sethi Date: Wed, 16 Oct 2024 15:43:03 +0530 Subject: [PATCH 34/80] Update docker-compose.yml --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0341a4d0..09b6e24a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,7 +53,7 @@ services: condition: service_started backend: condition: service_started - command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=1 -l DEBUG + command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=4 -l DEBUG restart: unless-stopped celery_nmt: From c211d4a21b330ea42b27bd63393bb34a255fe6ce Mon Sep 17 00:00:00 2001 From: Ishvinder Sethi Date: Fri, 18 Oct 2024 11:15:38 +0530 Subject: [PATCH 35/80] Revert "Increase concurrency in ASR celery worker" --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 09b6e24a..0341a4d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,7 +53,7 @@ services: condition: service_started backend: condition: service_started - command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=4 -l DEBUG + command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=1 -l DEBUG restart: unless-stopped celery_nmt: From 596424ad5cd9572c844b8d1bcacbc63844ba731c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 18 Oct 2024 19:35:11 +0530 Subject: [PATCH 36/80] changes for csv bulk regenerate failed VOTR tasks --- backend/translation/views.py | 3 +- backend/voiceover/urls.py | 5 ++ backend/voiceover/views.py | 110 +++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/backend/translation/views.py b/backend/translation/views.py index 8686c7d2..64f6e651 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -2337,8 +2337,7 @@ def get_translation_report(request): def regenerate_translation_voiceover(task_id): task_obj = Task.objects.get(pk=task_id) - video = Video.objects.filter(id=task_obj.video_id).first() - transcription_task = Task.objects.filter(video=video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() + transcription_task = Task.objects.filter(video=task_obj.video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() if transcription_task is None: return False transcript = get_transcript_id(transcription_task) diff --git a/backend/voiceover/urls.py b/backend/voiceover/urls.py index 0cf95e70..7863af15 100644 --- a/backend/voiceover/urls.py +++ b/backend/voiceover/urls.py @@ -63,4 +63,9 @@ views.get_voiceover_report, name="get_voiceover_report", ), + path( + "csv_bulk_regenerate", + views.csv_bulk_regenerate, + name="csv_bulk_regenerate", + ), ] diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 07d92b73..1d074423 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1,3 +1,5 @@ +import csv +import io from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema from rest_framework import status @@ -7,6 +9,9 @@ authentication_classes, ) from rest_framework.response import Response +from task.tasks import celery_nmt_tts_call +from transcript.models import Transcript +from transcript.views import get_transcript_id from task.models import Task, TRANSLATION_VOICEOVER_EDIT from translation.utils import get_batch_translations_using_indictrans_nmt_api from translation.models import ( @@ -45,6 +50,8 @@ import regex from glossary.tmx.tmxservice import TMXService from organization.decorators import is_admin +from organization.models import Organization +from video.models import Video @api_view(["GET"]) def get_voice_over_export_types(request): @@ -2203,3 +2210,106 @@ def reopen_translation_voiceover_task(request): {"message": "Can not reopen this task."}, status=status.HTTP_400_BAD_REQUEST, ) + +@api_view(["POST"]) +def csv_bulk_regenerate(request): + """ + API Endpoint to upload a csv file to regenerate failed VOTR tasks + Endpoint: /voiceover/csv_bulk_regenerate/ + Method: POST + """ + + org_id = request.data.get("org_id") + csv_content = request.data.get("csv") + + try: + org = Organization.objects.get(pk=org_id) + except Organization.DoesNotExist: + return Response( + {"message": "Organization not found"}, status=status.HTTP_404_NOT_FOUND + ) + + if not org.organization_owners.filter(id=request.user.id).exists(): + return Response( + {"message": "You are not allowed to upload CSV."}, + status=status.HTTP_403_FORBIDDEN, + ) + + decrypted = base64.b64decode(csv_content).decode("utf-8") + task_ids = [] + with io.StringIO(decrypted) as fp: + reader = csv.reader(fp, delimiter=",", quotechar='"') + for row in reader: + if row: + task_ids.append(int(row[0])) + + if len(task_ids) > 30: + return Response( + {"message": "Number of task id's is greater than 30."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + errors = [] + + for task_id in task_ids: + try: + task_obj = Task.objects.get(pk=task_id) + if task_obj.video.project_id.organization_id.id != org_id: + errors.append( + { + "row_no": f"Task {task_id}", + "message": f"Task Id does not belong to your organization", + } + ) + continue + # add flower queue check + except Task.DoesNotExist: + errors.append( + { + "row_no": f"Task {task_id}", + "message": f"Task Id does not exists", + } + ) + continue + + voiceover_obj = get_voice_over_id(task_obj) + + if voiceover_obj is None: + errors.append( + { + "row_no": f"Task {task_id}", + "message": f"Voiceover object does not exists", + } + ) + continue + + voice_over = VoiceOver.objects.get(pk=voiceover_obj.id) + + if voice_over.translation.transcript == None: + transcription_task = Task.objects.filter(video=task_obj.video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() + if transcription_task is None: + errors.append( + { + "row_no": f"Task {task_id}", + "message": f"Transcription not completed yet for this VOTR task", + } + ) + continue + + transcript = get_transcript_id(transcription_task) + transcript_obj = Transcript.objects.get(pk=transcript.id) + translation = Translation.objects.filter(task=task_obj).first() + translation.transcript = transcript_obj + translation.save() + + if len(errors) > 0: + return Response( + {"message": "Invalid CSV", "response": errors}, + status=status.HTTP_400_BAD_REQUEST, + ) + else: + for task_id in task_ids: + celery_nmt_tts_call.delay(task_id) + return Response( + {"message": "CSV uploaded successfully"}, status=status.HTTP_200_OK + ) \ No newline at end of file From 1ba1d2e41bce86d75266a511d4d13acd07828084 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 28 Oct 2024 17:32:08 +0530 Subject: [PATCH 37/80] add fast_audio flag --- backend/voiceover/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 1d074423..32b4b2e0 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -378,6 +378,7 @@ def get_payload(request): ) if voice_over.voice_over_type == "MACHINE_GENERATED": input_sentences = [] + fast_audio_threshold = 20 if task.target_language != "sa" else 16 for text, index in translation_payload: audio_index = str(start_offset + index) if audio_index in voice_over.payload["payload"].keys(): @@ -419,6 +420,7 @@ def get_payload(request): "audio" ], "audio_speed": 1, + "fast_audio": True if len(transcription_text)/t_d < fast_audio_threshold else False, } ) payload = {"payload": sentences_list} @@ -1031,7 +1033,7 @@ def save_voice_over(request): print("Saved IP Translation with inprogress") translation = inprogress_translation # Check if the transcript has a user - if task.user != request.user: + if task.user == request.user: return Response( {"message": "You are not allowed to update this voice_over."}, status=status.HTTP_400_BAD_REQUEST, From b0edcc0544a3f6c0d421ff38ebd2ab839cafe881 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 28 Oct 2024 17:32:56 +0530 Subject: [PATCH 38/80] add fast_audio flag --- backend/voiceover/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 32b4b2e0..b48fe4ca 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1033,7 +1033,7 @@ def save_voice_over(request): print("Saved IP Translation with inprogress") translation = inprogress_translation # Check if the transcript has a user - if task.user == request.user: + if task.user != request.user: return Response( {"message": "You are not allowed to update this voice_over."}, status=status.HTTP_400_BAD_REQUEST, From f017a910f2c62fc4a7159ccdcbb86c90e46979e0 Mon Sep 17 00:00:00 2001 From: Ishvinder Sethi Date: Tue, 29 Oct 2024 11:45:55 +0530 Subject: [PATCH 39/80] Revert "Revert "Increase concurrency in ASR celery worker"" --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0341a4d0..09b6e24a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,7 +53,7 @@ services: condition: service_started backend: condition: service_started - command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=1 -l DEBUG + command: python3 -m celery -A backend worker -Q asr_tts -n asr_tts_worker --concurrency=4 -l DEBUG restart: unless-stopped celery_nmt: From 7f1a68cd9cd5771fa09b2c2d390e970ec6312636 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 30 Oct 2024 10:58:07 +0530 Subject: [PATCH 40/80] changes for fast_audio flag --- backend/voiceover/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index b48fe4ca..628c01dc 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -379,6 +379,7 @@ def get_payload(request): if voice_over.voice_over_type == "MACHINE_GENERATED": input_sentences = [] fast_audio_threshold = 20 if task.target_language != "sa" else 16 + moderate_audio_threshold = 16 if task.target_language != "sa" else 12 for text, index in translation_payload: audio_index = str(start_offset + index) if audio_index in voice_over.payload["payload"].keys(): @@ -408,6 +409,7 @@ def get_payload(request): + float(time_difference.split(":")[1]) * 60 + float(time_difference.split(":")[2]) ) + text_length_per_second = len(transcription_text)/t_d sentences_list.append( { "id": str(int(audio_index) + 1), @@ -420,7 +422,7 @@ def get_payload(request): "audio" ], "audio_speed": 1, - "fast_audio": True if len(transcription_text)/t_d < fast_audio_threshold else False, + "fast_audio": 0 if text_length_per_second < moderate_audio_threshold else 1 if text_length_per_second < fast_audio_threshold else 2, } ) payload = {"payload": sentences_list} From 44af236fe5c593770a0284cb4a9dce42a1667612 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 30 Oct 2024 16:40:16 +0530 Subject: [PATCH 41/80] fixed minor bug in complete transcription task --- backend/transcript/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/transcript/views.py b/backend/transcript/views.py index 561941f4..f1ec8d3c 100644 --- a/backend/transcript/views.py +++ b/backend/transcript/views.py @@ -2111,7 +2111,7 @@ def save_transcription(request): ) for item in transcript_obj.payload["payload"]: item['verbatim_text'] = item['text'] - item['text'] = item['paraphrased_text'] if item['paraphrased_text'] is not None else item['verbatim_text'] + item['text'] = item['paraphrased_text'] if 'paraphrased_text' in item and item['paraphrased_text'] is not None else item['verbatim_text'] transcript_obj.save() task.status = "COMPLETE" task.save() From d0565d97ee8e4f0f1c92923fd58c2e298ba8d8ec Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 1 Nov 2024 16:07:06 +0530 Subject: [PATCH 42/80] minor fix for fast audio flag in auto save call --- backend/voiceover/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 628c01dc..b2cef587 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1405,6 +1405,8 @@ def save_voice_over(request): if voice_over_obj is not None and int( payload["payload"][0]["id"] ) == int(offset): + fast_audio_threshold = 20 if task.target_language != "sa" else 16 + moderate_audio_threshold = 16 if task.target_language != "sa" else 12 for i in range(len(payload["payload"])): start_time = payload["payload"][i]["start_time"] end_time = payload["payload"][i]["end_time"] @@ -1492,6 +1494,7 @@ def save_voice_over(request): } ) else: + text_length_per_second = len(transcription_text)/t_d voice_over_obj.payload["payload"][ str(start_offset + i) ] = { @@ -1531,6 +1534,7 @@ def save_voice_over(request): "transcription_text": payload["payload"][i][ "transcription_text" ], + "fast_audio": 0 if text_length_per_second < moderate_audio_threshold else 1 if text_length_per_second < fast_audio_threshold else 2, } ) voice_over_obj.save() From fb9b84b98a9545be98d281fd5d57a423086d9a03 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 4 Nov 2024 10:12:36 +0530 Subject: [PATCH 43/80] fix zero division error --- backend/voiceover/views.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index b2cef587..66036b3a 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -409,7 +409,10 @@ def get_payload(request): + float(time_difference.split(":")[1]) * 60 + float(time_difference.split(":")[2]) ) - text_length_per_second = len(transcription_text)/t_d + try: + text_length_per_second = len(transcription_text)/t_d + except ZeroDivisionError: + text_length_per_second = 0 sentences_list.append( { "id": str(int(audio_index) + 1), @@ -1494,7 +1497,10 @@ def save_voice_over(request): } ) else: - text_length_per_second = len(transcription_text)/t_d + try: + text_length_per_second = len(transcription_text)/t_d + except ZeroDivisionError: + text_length_per_second = 0 voice_over_obj.payload["payload"][ str(start_offset + i) ] = { From 9fcf9323792707820da4b0a4a270f60f5d9d115d Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 4 Nov 2024 10:21:25 +0530 Subject: [PATCH 44/80] fix zero division error --- backend/voiceover/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 66036b3a..200b96dd 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -411,7 +411,7 @@ def get_payload(request): ) try: text_length_per_second = len(transcription_text)/t_d - except ZeroDivisionError: + except: text_length_per_second = 0 sentences_list.append( { @@ -1499,7 +1499,7 @@ def save_voice_over(request): else: try: text_length_per_second = len(transcription_text)/t_d - except ZeroDivisionError: + except: text_length_per_second = 0 voice_over_obj.payload["payload"][ str(start_offset + i) From c6603bf1d5a8f262fca368db0e5689c18a5fc9a3 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 4 Nov 2024 10:31:06 +0530 Subject: [PATCH 45/80] fix zero division error --- backend/voiceover/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 200b96dd..1f07be47 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -412,7 +412,7 @@ def get_payload(request): try: text_length_per_second = len(transcription_text)/t_d except: - text_length_per_second = 0 + text_length_per_second = 100 sentences_list.append( { "id": str(int(audio_index) + 1), @@ -1500,7 +1500,7 @@ def save_voice_over(request): try: text_length_per_second = len(transcription_text)/t_d except: - text_length_per_second = 0 + text_length_per_second = 100 voice_over_obj.payload["payload"][ str(start_offset + i) ] = { From a597de7817fbfe79d88292f6bc807a5a9d939fad Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Mon, 11 Nov 2024 15:30:45 +0530 Subject: [PATCH 46/80] add correct error message for regenerating voiceover for 0 duration segment --- backend/voiceover/utils.py | 2 ++ backend/voiceover/views.py | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 13ae1b61..7d3dd375 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -1227,6 +1227,8 @@ def adjust_audio(audio_file, original_time, audio_speed): elif audio_time_difference == 0: logging.info("No time difference") elif audio_time_difference < -0.001: + if original_time == 0: + raise ZeroDivisionError logging.info("Speed up the audio by %s", str(seconds / original_time)) speedup_factor = seconds / original_time if speedup_factor > 1.009: diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index 07d92b73..e801dad2 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -1171,9 +1171,15 @@ def save_voice_over(request): if voice_over.voice_over_type == "MANUALLY_CREATED": voiceover_adjusted = adjust_voiceover(translation_payload) else: - voiceover_machine_generated = generate_voiceover_payload( - translation_payload, task.target_language, task - ) + try: + voiceover_machine_generated = generate_voiceover_payload( + translation_payload, task.target_language, task + ) + except ZeroDivisionError: + return Response( + {"message": "Cannot generate voiceover due to 0 duration for a segment"}, + status=status.HTTP_400_BAD_REQUEST, + ) if request.data.get("final"): if ( VoiceOver.objects.filter(status=VOICEOVER_EDIT_COMPLETE) From 4d4a0453dd7ab6fd92c9b3cd4c33b2ed3ffdbd0c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 12 Nov 2024 11:33:21 +0530 Subject: [PATCH 47/80] fix a bug in VOTR task completion --- backend/voiceover/utils.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 7d3dd375..d3c22852 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -1360,6 +1360,23 @@ def integrate_all_audios(file_name, payload, video_duration): final_audio.export( file_name + "_" + str(previous_index) + ".ogg", format="ogg" ) + if "time_difference" not in payload["payload"][str(index)]: + start_time = payload["payload"][str(index)]["start_time"] + end_time = payload["payload"][str(index)]["end_time"] + time_difference = ( + datetime.strptime(end_time, "%H:%M:%S.%f") + - timedelta( + hours=float(start_time.split(":")[0]), + minutes=float(start_time.split(":")[1]), + seconds=float(start_time.split(":")[-1]), + ) + ).strftime("%H:%M:%S.%f") + t_d = ( + int(time_difference.split(":")[0]) * 3600 + + int(time_difference.split(":")[1]) * 60 + + float(time_difference.split(":")[2]) + ) + payload["payload"][str(index)]["time_difference"] = t_d if index == length_payload - 1: original_time = payload["payload"][str(index)]["time_difference"] end_time = payload["payload"][str(index)]["end_time"] From 6f7a9d3c836e6f0c62d3cf79072a04b51ea44b60 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 12 Nov 2024 17:06:47 +0530 Subject: [PATCH 48/80] add send users active tasks email --- backend/backend/celery.py | 4 +++ backend/user_reports.py | 63 +++++++++++++++++++++++++++++++++++++++ backend/users/tasks.py | 3 ++ 3 files changed, 70 insertions(+) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 3be85514..f6ee3536 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -32,6 +32,10 @@ "task": "send_completed_tasks_mail", "schedule": crontab(minute=0, hour="*/6"), # execute 4 times in a day }, + "Send_mail_to_users_active": { + "task": "send_active_tasks_mail", + "schedule": crontab(minute=0, hour="11"), + }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", "schedule": crontab(minute=0, hour=1), # execute everyday at 1 am diff --git a/backend/user_reports.py b/backend/user_reports.py index 33578222..60aaee40 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -113,6 +113,69 @@ def get_completed_tasks(): else: html_table_df_tasks = "" +def get_active_tasks(): + users = User.objects.all() + + for member in list(users): + tasks_managed = [] + tasks = ( + Task.objects + .filter(status__in=["INPROGRESS", "SELECTED_SOURCE"]) + .filter(is_active=True) + .filter(user=member) + ) + for task in tasks: + tasks_managed.append( + { + "Project Name": task.video.project_id.title, + "Project Id": task.video.project_id.id, + "Task ID": task.id, + "Task Type": task.get_task_type_label, + } + ) + if len(tasks_managed) > 0: + df = pd.DataFrame.from_records(tasks_managed) + blankIndex = [""] * len(df) + df.index = blankIndex + html_table_df_tasks = build_table( + df, + "orange_light", + font_size="medium", + text_align="left", + width="auto", + index=False, + ) + message = ( + "Hope you are doing great " + + str(member.first_name + " " + member.last_name) + + ",\n Following tasks are active now." + ) + + email_to_send = ( + "

" + + message + + "


Active Tasks Reports

" + + html_table_df_tasks + ) + logging.info("Sending Mail to %s", member.email) + + compiled_msg = send_email_template_with_attachment( + subject=f"{app_name} - Active Tasks Report", + username=[member.email], + message=email_to_send, + ) + msg = EmailMultiAlternatives( + f"{app_name} - Active Tasks Report", + compiled_msg, + settings.DEFAULT_FROM_EMAIL, + [member.email], + ) + email_content = compiled_msg + html_table_df_tasks + msg.attach_alternative(email_content, "text/html") + msg.send() + else: + html_table_df_tasks = "" + def get_new_tasks(): logging.info("Calculate Reports...") diff --git a/backend/users/tasks.py b/backend/users/tasks.py index 25953839..4632106e 100644 --- a/backend/users/tasks.py +++ b/backend/users/tasks.py @@ -12,6 +12,9 @@ def send_completed_tasks_mail(): get_completed_tasks() +@shared_task(name="send_active_tasks_mail") +def send_active_tasks_mail(): + get_active_tasks() @shared_task(name="send_new_tasks_mail") def send_new_tasks_mail(): From 1805090a151b30339e8153884c4ae5fc2fe5b386 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 12 Nov 2024 17:27:17 +0530 Subject: [PATCH 49/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index f6ee3536..2d82f160 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute=0, hour="11"), + "schedule": crontab(minute=0, hour=23), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From 9bd040994c7557d9e2d3c38edd3e7de47614de70 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 13 Nov 2024 14:51:36 +0530 Subject: [PATCH 50/80] add send users active tasks email --- backend/backend/celery.py | 2 +- backend/user_reports.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 2d82f160..15c2e44f 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute=0, hour=23), + "schedule": crontab(minute=0, hour="*/48"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", diff --git a/backend/user_reports.py b/backend/user_reports.py index 60aaee40..e8fe49e0 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,7 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.all() + users = User.objects.filter(id=64) for member in list(users): tasks_managed = [] From 59f0da5d2b000aab295a9c3747f5573c2ec4833a Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 13 Nov 2024 15:52:10 +0530 Subject: [PATCH 51/80] add send users active tasks email --- backend/user_reports.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/user_reports.py b/backend/user_reports.py index e8fe49e0..08a38c03 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -125,12 +125,14 @@ def get_active_tasks(): .filter(user=member) ) for task in tasks: + type = "voiceover" if task.task_type.find("VOICEOVER") else "translate" if task.task_type.find("TRANSLATION") else "transcript" tasks_managed.append( { "Project Name": task.video.project_id.title, "Project Id": task.video.project_id.id, "Task ID": task.id, "Task Type": task.get_task_type_label, + "Task Link": "https://chitralekha.ai4bharat.org/#/task/"+str(task.id)+"/"+type } ) if len(tasks_managed) > 0: From 0cef38ccfccad3dd574e44f8459a4206285d9800 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 13 Nov 2024 15:56:40 +0530 Subject: [PATCH 52/80] add send users active tasks email --- backend/user_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/user_reports.py b/backend/user_reports.py index 08a38c03..47a06809 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -172,7 +172,7 @@ def get_active_tasks(): settings.DEFAULT_FROM_EMAIL, [member.email], ) - email_content = compiled_msg + html_table_df_tasks + email_content = compiled_msg msg.attach_alternative(email_content, "text/html") msg.send() else: From 5d4dc3670ac865dc58cc1f7caea0e087bb8ef481 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 09:41:16 +0530 Subject: [PATCH 53/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 15c2e44f..fd4b1eaf 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute=0, hour="*/48"), + "schedule": crontab(minute=0, hour=10), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From cf1377a733db84d3b3b306b91a58543e909cc3bb Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 10:17:51 +0530 Subject: [PATCH 54/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index fd4b1eaf..51069443 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute=0, hour=10), + "schedule": crontab(minute="0,30", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From affbaa3ea0eb1f9492e891c91a4e558c51691f7b Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 10:40:14 +0530 Subject: [PATCH 55/80] add send users active tasks email --- backend/user_reports.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/user_reports.py b/backend/user_reports.py index 47a06809..ff2d9310 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -125,14 +125,20 @@ def get_active_tasks(): .filter(user=member) ) for task in tasks: - type = "voiceover" if task.task_type.find("VOICEOVER") else "translate" if task.task_type.find("TRANSLATION") else "transcript" + if task.get_task_type_label.count("VoiceOver"): + type = "voiceover" + elif task.get_task_type_label.count("Translation"): + type = "translate" + else: + type = "transcript" + task_link = f"https://chitralekha.ai4bharat.org/#/task/{task.id}/{type}" tasks_managed.append( { "Project Name": task.video.project_id.title, "Project Id": task.video.project_id.id, "Task ID": task.id, "Task Type": task.get_task_type_label, - "Task Link": "https://chitralekha.ai4bharat.org/#/task/"+str(task.id)+"/"+type + "Task Link": f'Open Task' } ) if len(tasks_managed) > 0: @@ -146,6 +152,7 @@ def get_active_tasks(): text_align="left", width="auto", index=False, + escape=False, ) message = ( "Hope you are doing great " From 8615d430214989eba6c7d6539bf85ab232a3e060 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 16:37:47 +0530 Subject: [PATCH 56/80] add send users active tasks email --- backend/user_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/user_reports.py b/backend/user_reports.py index ff2d9310..47fd091d 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,7 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.filter(id=64) + users = User.objects.filter(id__in=[3, 71, 121, 199, 200, 202, 205, 207, 208, 209, 210, 216, 217, 218, 220, 221, 224, 231, 238, 245, 257, 262, 263, 265, 270, 274, 275, 277, 278, 279, 285, 454, 572, 573, 596, 677, 678, 683, 685, 688, 705, 706, 707, 708, 709, 710, 711, 714, 715, 717, 718, 719, 724, 725, 743, 746, 747, 847, 850, 853, 896, 897, 905, 909, 912, 1075, 1078, 1089, 1103, 1104, 1105, 1141, 1165, 1179, 1187, 1201, 1206, 1226, 1235, 1257, 1260, 1269, 1279, 1282, 1301, 1303, 1305, 1307, 1314, 1324, 1330, 1352, 1353, 1358, 1366, 1385, 1390, 64]) for member in list(users): tasks_managed = [] From cc27dc84308b2b193a2c942731a8f9d6e8422a92 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 16:40:51 +0530 Subject: [PATCH 57/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 51069443..4f9081df 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="0,30", hour="*"), + "schedule": crontab(minute="45", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From b8f2a2c97202d4cfa2dad2a9a69ffef061e0d867 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 16:48:01 +0530 Subject: [PATCH 58/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 4f9081df..041b80c3 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="45", hour="*"), + "schedule": crontab(minute="50", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From 2c69146fd35502b2ac73aee3aa094dd991fef22c Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 16:49:54 +0530 Subject: [PATCH 59/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 041b80c3..3a582c29 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="50", hour="*"), + "schedule": crontab(minute="55", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From 533b5ef5857df2f8e122fa8318d5185d816999cc Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 16:55:00 +0530 Subject: [PATCH 60/80] add send users active tasks email --- backend/backend/celery.py | 2 +- backend/user_reports.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 3a582c29..11ac2a31 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="55", hour="*"), + "schedule": crontab(minute="5", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", diff --git a/backend/user_reports.py b/backend/user_reports.py index 47fd091d..a19d3ff0 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,8 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.filter(id__in=[3, 71, 121, 199, 200, 202, 205, 207, 208, 209, 210, 216, 217, 218, 220, 221, 224, 231, 238, 245, 257, 262, 263, 265, 270, 274, 275, 277, 278, 279, 285, 454, 572, 573, 596, 677, 678, 683, 685, 688, 705, 706, 707, 708, 709, 710, 711, 714, 715, 717, 718, 719, 724, 725, 743, 746, 747, 847, 850, 853, 896, 897, 905, 909, 912, 1075, 1078, 1089, 1103, 1104, 1105, 1141, 1165, 1179, 1187, 1201, 1206, 1226, 1235, 1257, 1260, 1269, 1279, 1282, 1301, 1303, 1305, 1307, 1314, 1324, 1330, 1352, 1353, 1358, 1366, 1385, 1390, 64]) - + users = User.objects.filter(id__in=[1400, 1414, 1416, 1419, 1420, 1422, 1426, 1427, 1433, 1434, 1435, 1439, 1446, 1451, 1453, 1457, 1460, 1461, 1463, 1469, 1473, 1482, 1483, 1484, 1486, 1487, 1492, 1496, 1497, 1498, 1511, 1513, 1514, 1515, 1524, 1525, 1526, 1528, 1529, 1531, 1532, 1541, 1542, 1544, 1554, 1558, 1563, 1564, 1573, 1574, 1585, 1592, 1593, 1594, 1597, 1599, 1602, 1603, 1604, 1611, 1612, 1617, 1623, 1625, 1627, 1633, 1638, 1639, 1652, 1653, 1654, 1655, 1658, 1660, 1662, 1664, 1666, 1668, 1669, 1672, 1680, 1689, 1690, 1693, 1695, 1696, 1697, 1698, 1700, 1702, 1703, 1707, 1714, 1716, 1717, 1721, 1722, 1724, 64]) for member in list(users): tasks_managed = [] tasks = ( From 957b10a2775f74ab3452760095765e444e4c1a55 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 17:28:37 +0530 Subject: [PATCH 61/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 11ac2a31..51069443 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="5", hour="*"), + "schedule": crontab(minute="0,30", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From 6b54cee818f999f21d1eecce4863090f676e5333 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 17:30:24 +0530 Subject: [PATCH 62/80] add send users active tasks email --- backend/backend/celery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 51069443..b4575a5b 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="0,30", hour="*"), + "schedule": crontab(minute="10,40", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", From 593899577dd680cce82099f22191e3c1fee8ebc1 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 17:33:04 +0530 Subject: [PATCH 63/80] add send users active tasks email --- backend/backend/celery.py | 2 +- backend/user_reports.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index b4575a5b..51069443 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="10,40", hour="*"), + "schedule": crontab(minute="0,30", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", diff --git a/backend/user_reports.py b/backend/user_reports.py index a19d3ff0..535af7b3 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,7 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.filter(id__in=[1400, 1414, 1416, 1419, 1420, 1422, 1426, 1427, 1433, 1434, 1435, 1439, 1446, 1451, 1453, 1457, 1460, 1461, 1463, 1469, 1473, 1482, 1483, 1484, 1486, 1487, 1492, 1496, 1497, 1498, 1511, 1513, 1514, 1515, 1524, 1525, 1526, 1528, 1529, 1531, 1532, 1541, 1542, 1544, 1554, 1558, 1563, 1564, 1573, 1574, 1585, 1592, 1593, 1594, 1597, 1599, 1602, 1603, 1604, 1611, 1612, 1617, 1623, 1625, 1627, 1633, 1638, 1639, 1652, 1653, 1654, 1655, 1658, 1660, 1662, 1664, 1666, 1668, 1669, 1672, 1680, 1689, 1690, 1693, 1695, 1696, 1697, 1698, 1700, 1702, 1703, 1707, 1714, 1716, 1717, 1721, 1722, 1724, 64]) + users = User.objects.filter(id__in=[1725, 1726, 1731, 1734, 1738, 1739, 1742, 1743, 1745, 1747, 1748, 1752, 1753, 1754, 1756, 1758, 1759, 1761, 1763, 1764, 1765, 1766, 1769, 1770, 1771, 1773, 1774, 1777, 1778, 1785, 1786, 1788, 1795, 1807, 1809, 1810, 1812, 1817, 1818, 1820, 1823, 1826, 1827, 1835, 1837, 1842, 1844, 1845, 1848, 1849, 1851, 1853, 1854, 1855, 1856, 1859, 1861, 1864, 1866, 1873, 1874, 1878, 1879, 1881, 1882, 1884, 1885, 1886, 1887, 1888, 1891, 1892, 1893, 1894, 1895, 1898, 1900, 1901, 1906, 1907, 1910, 1911, 1912, 1913, 1914, 1918, 1920, 1921, 1923, 1924, 1925, 1926, 1929, 1930, 1931, 1933, 1934, 1935, 64]) for member in list(users): tasks_managed = [] tasks = ( From ef7f75a23a6152983a30d2fcbd330b0e3c520823 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 17:36:14 +0530 Subject: [PATCH 64/80] add send users active tasks email --- backend/backend/celery.py | 2 +- backend/user_reports.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 51069443..ccef141a 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="0,30", hour="*"), + "schedule": crontab(minute="20,50", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", diff --git a/backend/user_reports.py b/backend/user_reports.py index 535af7b3..eec01ca3 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,7 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.filter(id__in=[1725, 1726, 1731, 1734, 1738, 1739, 1742, 1743, 1745, 1747, 1748, 1752, 1753, 1754, 1756, 1758, 1759, 1761, 1763, 1764, 1765, 1766, 1769, 1770, 1771, 1773, 1774, 1777, 1778, 1785, 1786, 1788, 1795, 1807, 1809, 1810, 1812, 1817, 1818, 1820, 1823, 1826, 1827, 1835, 1837, 1842, 1844, 1845, 1848, 1849, 1851, 1853, 1854, 1855, 1856, 1859, 1861, 1864, 1866, 1873, 1874, 1878, 1879, 1881, 1882, 1884, 1885, 1886, 1887, 1888, 1891, 1892, 1893, 1894, 1895, 1898, 1900, 1901, 1906, 1907, 1910, 1911, 1912, 1913, 1914, 1918, 1920, 1921, 1923, 1924, 1925, 1926, 1929, 1930, 1931, 1933, 1934, 1935, 64]) + users = User.objects.filter(id__in=[1939, 1942, 1943, 1944, 1945, 1947, 1952, 1955, 1957, 1958, 1959, 1960, 1963, 1967, 1968, 1971, 1973, 1984, 1985, 1986, 1987, 2005, 2007, 2011, 2015, 2018, 2023, 2028, 2030, 2035, 2040, 2043, 2044, 2046, 2047, 2048, 2049, 2050, 2053, 2054, 2057, 2059, 2063, 2065, 2066, 2071, 2075, 2080, 2082, 2087, 2089, 2090, 2092, 2096, 2098, 2099, 2101, 2102, 2104, 2105, 2106, 2109, 2112, 2113, 2115, 2135, 2136, 2142, 2143, 2144, 2157, 2159, 2160, 2170, 2172, 2173, 2177, 2178, 2190, 2193, 2195, 2198, 2200, 2204, 2206, 2210, 2220, 2221, 2224, 2231, 2232, 2236, 2239, 2241, 2242, 2243, 2244, 2247, 64]) for member in list(users): tasks_managed = [] tasks = ( From efba2779a6fa9ce46ef1af03df143c37fb12b7b3 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 14 Nov 2024 17:38:33 +0530 Subject: [PATCH 65/80] add send users active tasks email --- backend/backend/celery.py | 2 +- backend/user_reports.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index ccef141a..6b5d6ff3 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -34,7 +34,7 @@ }, "Send_mail_to_users_active": { "task": "send_active_tasks_mail", - "schedule": crontab(minute="20,50", hour="*"), + "schedule": crontab(minute="0,40", hour="*"), }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", diff --git a/backend/user_reports.py b/backend/user_reports.py index eec01ca3..b2261ab6 100644 --- a/backend/user_reports.py +++ b/backend/user_reports.py @@ -114,7 +114,7 @@ def get_completed_tasks(): html_table_df_tasks = "" def get_active_tasks(): - users = User.objects.filter(id__in=[1939, 1942, 1943, 1944, 1945, 1947, 1952, 1955, 1957, 1958, 1959, 1960, 1963, 1967, 1968, 1971, 1973, 1984, 1985, 1986, 1987, 2005, 2007, 2011, 2015, 2018, 2023, 2028, 2030, 2035, 2040, 2043, 2044, 2046, 2047, 2048, 2049, 2050, 2053, 2054, 2057, 2059, 2063, 2065, 2066, 2071, 2075, 2080, 2082, 2087, 2089, 2090, 2092, 2096, 2098, 2099, 2101, 2102, 2104, 2105, 2106, 2109, 2112, 2113, 2115, 2135, 2136, 2142, 2143, 2144, 2157, 2159, 2160, 2170, 2172, 2173, 2177, 2178, 2190, 2193, 2195, 2198, 2200, 2204, 2206, 2210, 2220, 2221, 2224, 2231, 2232, 2236, 2239, 2241, 2242, 2243, 2244, 2247, 64]) + users = User.objects.filter(id__in=[2248, 2252, 2253, 2254, 2255, 2256, 2257, 2259, 2263, 2264, 2266, 2268, 2273, 2278, 2281, 2282, 2283, 2286, 2289, 2291, 2293, 2296, 2299, 2300, 2320, 2322, 2326, 2328, 2329, 2336, 2337, 2338, 2339, 2340, 2343, 2344, 2345, 2351, 2353, 2360, 2361, 2365, 2374, 2376, 2379, 2390, 2395, 2402, 2405, 2459, 2461, 2471, 2472, 2480, 2485, 2486, 2487, 2550, 2559, 64]) for member in list(users): tasks_managed = [] tasks = ( From 95dd3d4a9dda8f5c0929a538a8071558ce293c86 Mon Sep 17 00:00:00 2001 From: Kartik Virendra Rajput <88619994+kartikvirendrar@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:14:12 +0530 Subject: [PATCH 66/80] Remove send active tasks email --- backend/backend/celery.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/backend/celery.py b/backend/backend/celery.py index 6b5d6ff3..3be85514 100644 --- a/backend/backend/celery.py +++ b/backend/backend/celery.py @@ -32,10 +32,6 @@ "task": "send_completed_tasks_mail", "schedule": crontab(minute=0, hour="*/6"), # execute 4 times in a day }, - "Send_mail_to_users_active": { - "task": "send_active_tasks_mail", - "schedule": crontab(minute="0,40", hour="*"), - }, "Send_mail_to_managers_new": { "task": "send_new_tasks_mail", "schedule": crontab(minute=0, hour=1), # execute everyday at 1 am From 42b690975725638f10a0bc698365c6dddd502cab Mon Sep 17 00:00:00 2001 From: Kartik Virendra Rajput <88619994+kartikvirendrar@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:10:55 +0530 Subject: [PATCH 67/80] handle an edge case of negative duration --- backend/voiceover/utils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 3c8b83dc..5217c61f 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -1137,7 +1137,7 @@ def check_audio_completion(voice_over_obj): for index, payload in enumerate(voice_over_obj.translation.payload["payload"]): if str(index) in voice_over_obj.payload["payload"].keys(): - if (get_original_duration(voice_over_obj.payload["payload"][str(index)]["start_time"], voice_over_obj.payload["payload"][str(index)]["end_time"]) < 0.1): + if (get_original_duration_neg(voice_over_obj.payload["payload"][str(index)]["start_time"], voice_over_obj.payload["payload"][str(index)]["end_time"]) < 0.1): missing_cards.append( { "card_number": index + 1, @@ -1292,6 +1292,14 @@ def get_original_duration(start_time, end_time): ) return t_d +def get_original_duration_neg(start_time, end_time): + start = datetime.strptime(start_time, "%H:%M:%S.%f") + end = datetime.strptime(end_time, "%H:%M:%S.%f") + + time_difference = (end - start).total_seconds() + + return time_difference + def integrate_all_audios(file_name, payload, video_duration): length_payload = len(payload["payload"]) From 43bc297bd85e1d12323c099d265cf3bc73c1865d Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 22 Nov 2024 10:48:15 +0530 Subject: [PATCH 68/80] minor bug fix for regenerate VOTR tasks using bulk_csv_upload --- backend/voiceover/views.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index ab64a184..c7d78695 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -91,6 +91,12 @@ def get_voice_over_id(task): .filter(status="VOICEOVER_EDIT_INPROGRESS") .first() ) + if task.status == "FAILED": + voice_over_id = ( + voice_over.filter(video=task.video) + .filter(status="VOICEOVER_SELECT_SOURCE") + .first() + ) else: if task.status == "NEW": voice_over_id = ( @@ -2260,7 +2266,7 @@ def csv_bulk_regenerate(request): with io.StringIO(decrypted) as fp: reader = csv.reader(fp, delimiter=",", quotechar='"') for row in reader: - if row: + if row and row[0].strip(): task_ids.append(int(row[0])) if len(task_ids) > 30: From b3cc893a768cb02865396f9aedcc3da015344ab2 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 11 Dec 2024 18:28:48 +0530 Subject: [PATCH 69/80] add task id and language in logging info --- backend/voiceover/utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/voiceover/utils.py b/backend/voiceover/utils.py index 5217c61f..df5dec0e 100644 --- a/backend/voiceover/utils.py +++ b/backend/voiceover/utils.py @@ -222,8 +222,8 @@ def upload_zip_to_azure(zip_file_path): return blob_client_zip.url -def get_tts_output(tts_input, target_language, multiple_speaker, gender): - logging.info("Calling TTS API") +def get_tts_output(tts_input, target_language, multiple_speaker, gender, id): + logging.info("Calling TTS API for %s task in %s language", str(id), str(target_language)) tts_url = get_tts_url(target_language) if tts_url is None: return { @@ -285,6 +285,7 @@ def generate_tts_output( target_language, translation_obj.video.multiple_speaker, gender.lower(), + translation_obj.id, ) logging.info("output generated") else: @@ -306,6 +307,7 @@ def generate_tts_output( target_language, translation_obj.video.multiple_speaker, speaker_info[speaker_id], + translation_obj.id, ) if ( type(speaker_tts_output) != dict @@ -1035,7 +1037,7 @@ def generate_voiceover_payload(translation_payload, target_language, task): else: gender = task.video.gender voiceover_machine_generated = get_tts_output( - tts_input, target_language, task.video.multiple_speaker, gender.lower() + tts_input, target_language, task.video.multiple_speaker, gender.lower(), task.id ) if ( type(voiceover_machine_generated) == dict From 64b44082fbe945d0651868bbe9b2f0346ac67495 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 12 Dec 2024 15:33:46 +0530 Subject: [PATCH 70/80] minor change in inspect queue --- backend/task/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/task/views.py b/backend/task/views.py index b98fc0e1..e2bfee9d 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -3199,7 +3199,7 @@ def inspect_queue(self, request): except: task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) elif elem["name"] == "voiceover.tasks.celery_integration": - task_obj["task_id"] = eval(elem["args"].split(",")[2]) + task_obj["task_id"] = eval(elem["args"].split(",")[3]) elif elem["name"] == "voiceover.tasks.export_voiceover_async": task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) else: From 034278a8bc3168bbf78a35674db9735db60d2cd3 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 13 Dec 2024 11:30:15 +0530 Subject: [PATCH 71/80] minor changes for azure blob videos --- backend/video/utils.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/backend/video/utils.py b/backend/video/utils.py index d1afe7aa..9bbfeaa2 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -27,6 +27,8 @@ from config import youtube_api_key from googleapiclient.discovery import build import re +from moviepy.editor import VideoFileClip +from math import floor ydl = YoutubeDL({"format": "best"}) @@ -521,10 +523,17 @@ def get_video_func(request): duration_iso8601 = video["contentDetails"]["duration"] duration = timedelta(seconds=iso8601_duration_to_seconds(duration_iso8601)) except: - return Response( - {"message": "This is an invalid video URL."}, - status=status.HTTP_400_BAD_REQUEST, - ) + if "blob.core.windows.net" in url: + info = ydl.extract_info(url, download=False) + title = info["title"] + video = VideoFileClip(url) + duration = timedelta(seconds=floor(video.duration)) + direct_video_url = url + else: + return Response( + {"message": "This is an invalid video URL."}, + status=status.HTTP_400_BAD_REQUEST, + ) # if title[-4:] == ".mp4" and "youtube.com" not in normalized_url: # return Response( From 3da7126fa79ee089d20f67f791667c2cbbf8fc56 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Fri, 13 Dec 2024 14:37:14 +0530 Subject: [PATCH 72/80] minor bug fix in celery inspection --- backend/task/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/task/views.py b/backend/task/views.py index e2bfee9d..b98fc0e1 100644 --- a/backend/task/views.py +++ b/backend/task/views.py @@ -3199,7 +3199,7 @@ def inspect_queue(self, request): except: task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) elif elem["name"] == "voiceover.tasks.celery_integration": - task_obj["task_id"] = eval(elem["args"].split(",")[3]) + task_obj["task_id"] = eval(elem["args"].split(",")[2]) elif elem["name"] == "voiceover.tasks.export_voiceover_async": task_obj["task_id"] = eval(elem["args"].split(",")[0].split("(")[1]) else: From 19993e4872d4d2e5add9fb7ca45c973c8cc31997 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Dec 2024 12:14:06 +0530 Subject: [PATCH 73/80] minor changes for azure blob video url --- backend/video/utils.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/backend/video/utils.py b/backend/video/utils.py index 9bbfeaa2..94bd9f1b 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -493,14 +493,22 @@ def get_video_func(request): ) try: + if "blob.core.windows.net" in url: + info = ydl.extract_info(url, download=False) + title = info["title"] + video = VideoFileClip(url) + duration = timedelta(seconds=floor(video.duration)) + direct_video_url = url + normalized_url = url + else: # Get the video info from the YouTube API - ( - direct_video_url, - normalized_url, - title, - duration, - direct_audio_url, - ) = get_data_from_google_video(url) + ( + direct_video_url, + normalized_url, + title, + duration, + direct_audio_url, + ) = get_data_from_google_video(url) except: direct_video_url = "" direct_audio_url = "" @@ -523,17 +531,10 @@ def get_video_func(request): duration_iso8601 = video["contentDetails"]["duration"] duration = timedelta(seconds=iso8601_duration_to_seconds(duration_iso8601)) except: - if "blob.core.windows.net" in url: - info = ydl.extract_info(url, download=False) - title = info["title"] - video = VideoFileClip(url) - duration = timedelta(seconds=floor(video.duration)) - direct_video_url = url - else: - return Response( - {"message": "This is an invalid video URL."}, - status=status.HTTP_400_BAD_REQUEST, - ) + return Response( + {"message": "This is an invalid video URL."}, + status=status.HTTP_400_BAD_REQUEST, + ) # if title[-4:] == ".mp4" and "youtube.com" not in normalized_url: # return Response( From 9c8e371db81a798da60bbce80174cadc4a88cde5 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Dec 2024 13:48:31 +0530 Subject: [PATCH 74/80] added changes for export filename changes --- backend/translation/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/translation/views.py b/backend/translation/views.py index 64f6e651..8e664236 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -302,11 +302,11 @@ def export_translation(request): status=status.HTTP_400_BAD_REQUEST, ) - content_type = "application/json" + content_type = translation.video.description or "description" if len(content) == 0: content = " " if return_file_content: - response = HttpResponse(json.dumps(content), content_type="application/json") + response = HttpResponse(json.dumps(content), content_type=content_type) return response response = HttpResponse(content, content_type=content_type) From dad65b3e4098e5fdf0480512da3ec1e55eb2a378 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Dec 2024 16:08:43 +0530 Subject: [PATCH 75/80] minor change for azure blob video --- backend/video/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/video/utils.py b/backend/video/utils.py index 94bd9f1b..81cb3e1a 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -494,8 +494,9 @@ def get_video_func(request): try: if "blob.core.windows.net" in url: - info = ydl.extract_info(url, download=False) - title = info["title"] + # info = ydl.extract_info(url, download=False) + # title = info["title"] + title = "azure blob video" video = VideoFileClip(url) duration = timedelta(seconds=floor(video.duration)) direct_video_url = url From f2a657deb7edaa0c4f8e74ded33fdb305b3f11c7 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Dec 2024 16:30:21 +0530 Subject: [PATCH 76/80] error logging for video api --- backend/video/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/video/utils.py b/backend/video/utils.py index 81cb3e1a..6950f48d 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -531,7 +531,8 @@ def get_video_func(request): title = video["snippet"]["title"] duration_iso8601 = video["contentDetails"]["duration"] duration = timedelta(seconds=iso8601_duration_to_seconds(duration_iso8601)) - except: + except Exception as e: + logging.error(e) return Response( {"message": "This is an invalid video URL."}, status=status.HTTP_400_BAD_REQUEST, From 9c61c5c9afcc50b30008def5f382038da5a79f19 Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Wed, 18 Dec 2024 16:34:17 +0530 Subject: [PATCH 77/80] changes for azure blob video --- backend/video/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/video/utils.py b/backend/video/utils.py index 6950f48d..23a80bca 100644 --- a/backend/video/utils.py +++ b/backend/video/utils.py @@ -494,9 +494,8 @@ def get_video_func(request): try: if "blob.core.windows.net" in url: - # info = ydl.extract_info(url, download=False) - # title = info["title"] - title = "azure blob video" + info = ydl.extract_info(url, download=False) + title = info["title"] video = VideoFileClip(url) duration = timedelta(seconds=floor(video.duration)) direct_video_url = url From 62e7af138e71263b10185929bdec50bba598260e Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Thu, 19 Dec 2024 17:19:05 +0530 Subject: [PATCH 78/80] changes for bulk regenerate VOTR --- backend/voiceover/views.py | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index c7d78695..c70ef096 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -2309,24 +2309,21 @@ def csv_bulk_regenerate(request): ) continue - voice_over = VoiceOver.objects.get(pk=voiceover_obj.id) - - if voice_over.translation.transcript == None: - transcription_task = Task.objects.filter(video=task_obj.video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() - if transcription_task is None: - errors.append( - { - "row_no": f"Task {task_id}", - "message": f"Transcription not completed yet for this VOTR task", - } - ) - continue + transcription_task = Task.objects.filter(video=task_obj.video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() + if transcription_task is None: + errors.append( + { + "row_no": f"Task {task_id}", + "message": f"Transcription not completed yet for this VOTR task", + } + ) + continue - transcript = get_transcript_id(transcription_task) - transcript_obj = Transcript.objects.get(pk=transcript.id) - translation = Translation.objects.filter(task=task_obj).first() - translation.transcript = transcript_obj - translation.save() + transcript = get_transcript_id(transcription_task) + transcript_obj = Transcript.objects.get(pk=transcript.id) + translation = Translation.objects.filter(task=task_obj).first() + translation.transcript = transcript_obj + translation.save() if len(errors) > 0: return Response( From c6a09a52b56f42afff5375b85b55a1cfc2661db0 Mon Sep 17 00:00:00 2001 From: Kartik Virendra Rajput <88619994+kartikvirendrar@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:54:13 +0530 Subject: [PATCH 79/80] Revert "added changes for export filename changes" --- backend/translation/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/translation/views.py b/backend/translation/views.py index 8e664236..64f6e651 100644 --- a/backend/translation/views.py +++ b/backend/translation/views.py @@ -302,11 +302,11 @@ def export_translation(request): status=status.HTTP_400_BAD_REQUEST, ) - content_type = translation.video.description or "description" + content_type = "application/json" if len(content) == 0: content = " " if return_file_content: - response = HttpResponse(json.dumps(content), content_type=content_type) + response = HttpResponse(json.dumps(content), content_type="application/json") return response response = HttpResponse(content, content_type=content_type) From bea0f08db8f2e29248f96e3b43d17df76150a3af Mon Sep 17 00:00:00 2001 From: kartikvirendrar Date: Tue, 24 Dec 2024 12:28:13 +0530 Subject: [PATCH 80/80] changes for bulk regenerate failed VOTR tasks --- backend/task/tasks.py | 117 ++++++++++++++++++------------------- backend/voiceover/views.py | 8 +++ 2 files changed, 66 insertions(+), 59 deletions(-) diff --git a/backend/task/tasks.py b/backend/task/tasks.py index 8004939b..4144272c 100644 --- a/backend/task/tasks.py +++ b/backend/task/tasks.py @@ -296,6 +296,8 @@ def celery_nmt_tts_call(task_id): task_obj.status = "FAILED" task_obj.is_active = False task_obj.save() + logging.info("Generating translation payload failed for %s", str(task_id)) + return else: if ( type(translation_obj.payload) == dict @@ -308,69 +310,66 @@ def celery_nmt_tts_call(task_id): task_obj.status = "SELECTED_SOURCE" # task_obj.is_active = True task_obj.save() - tts_payload = process_translation_payload( - translation_obj, task_obj.target_language - ) - if type(tts_payload) == dict and "message" in tts_payload.keys(): - message = tts_payload["message"] - logging.info("Error from TTS API") - voice_over_task.status = "FAILED" - voice_over_task.save() - # set_fail_for_translation_task(task) - return message - ( - tts_input, - target_language, - translation, - translation_id, - empty_sentences, - ) = tts_payload + tts_payload = process_translation_payload( + translation_obj, task_obj.target_language + ) + if type(tts_payload) == dict and "message" in tts_payload.keys(): + message = tts_payload["message"] + logging.info("Error from TTS API") + voice_over_task.status = "FAILED" + voice_over_task.save() + # set_fail_for_translation_task(task) + return message - generate_audio = task_obj.video.project_id.pre_generate_audio - tts_payload = generate_tts_output( - tts_input, - target_language, - translation, - translation_obj, - empty_sentences, - generate_audio, - ) - payloads = tts_payload + ( + tts_input, + target_language, + translation, + translation_id, + empty_sentences, + ) = tts_payload - existing_voiceover = VoiceOver.objects.filter(task=task_obj).first() + generate_audio = task_obj.video.project_id.pre_generate_audio + tts_payload = generate_tts_output( + tts_input, + target_language, + translation, + translation_obj, + empty_sentences, + generate_audio, + ) + payloads = tts_payload - print("Fetched voiceover", existing_voiceover) + existing_voiceover = VoiceOver.objects.filter(task=task_obj).first() - if existing_voiceover == None: - voiceover_obj = VoiceOver( - video=task_obj.video, - user=task_obj.user, - translation=translation_obj, - payload=tts_payload, - target_language=task_obj.target_language, - task=task_obj, - voice_over_type="MACHINE_GENERATED", - status="VOICEOVER_SELECT_SOURCE", - ) - voiceover_obj.save() - else: - existing_voiceover.payload = tts_payload - existing_voiceover.translation = translation_obj - existing_voiceover.save() - task_obj.is_active = True - task_obj.status = "SELECTED_SOURCE" - task_obj.save() - logging.info("Payload generated for TTS API for %s", str(task_id)) - if "message" in tts_payload: - task_obj.is_active = False - task_obj.status = "FAILED" - task_obj.save() - try: - send_mail_to_user(task_obj) - except: - logging.info("Error in sending mail") + print("Fetched voiceover", existing_voiceover) - # send_mail_to_user(task_obj) + if existing_voiceover == None: + voiceover_obj = VoiceOver( + video=task_obj.video, + user=task_obj.user, + translation=translation_obj, + payload=tts_payload, + target_language=task_obj.target_language, + task=task_obj, + voice_over_type="MACHINE_GENERATED", + status="VOICEOVER_SELECT_SOURCE", + ) + voiceover_obj.save() else: - logging.info("Translation already exists") + existing_voiceover.payload = tts_payload + existing_voiceover.translation = translation_obj + existing_voiceover.save() + task_obj.is_active = True + task_obj.status = "SELECTED_SOURCE" + task_obj.save() + logging.info("Payload generated for TTS API for %s", str(task_id)) + if "message" in tts_payload: + task_obj.is_active = False + task_obj.status = "FAILED" + task_obj.save() + try: + send_mail_to_user(task_obj) + except: + logging.info("Error in sending mail") \ No newline at end of file diff --git a/backend/voiceover/views.py b/backend/voiceover/views.py index c70ef096..067cdada 100644 --- a/backend/voiceover/views.py +++ b/backend/voiceover/views.py @@ -2308,6 +2308,14 @@ def csv_bulk_regenerate(request): } ) continue + + if voiceover_obj.status != "VOICEOVER_SELECT_SOURCE": + voiceover_obj.status = "VOICEOVER_SELECT_SOURCE" + voiceover_obj.save() + if task_obj.status != "SELECTED_SOURCE": + task_obj.status = "SELECTED_SOURCE" + task_obj.is_active = False + task_obj.save() transcription_task = Task.objects.filter(video=task_obj.video, task_type="TRANSCRIPTION_EDIT", status="COMPLETE").first() if transcription_task is None: