deepsync's picture
Update app.py
1659d1b
raw
history blame contribute delete
No virus
21.5 kB
import os
import gradio as gr
import pymongo
import pandas as pd
from bson import ObjectId
from dotenv import load_dotenv
import requests
from datetime import timedelta
from collections import defaultdict
load_dotenv()
video_status = {
"Not Assigned": "NOT_STARTED",
"Under Review": "NOT_STARTED",
"Dubbing Started": "DUBBING_STARTED",
"Waiting QA": "WAITING_QA",
"Sent to Client": "SENT_TO_CLIENT",
"Approved": "APPROVED",
"Rejected": "REJECTED",
"Churned": "CHURNED",
"Re-review Requested": "RE_REVIEW_REQUESTED"
}
HEADERS = {"x-api-key": os.environ.get('X-API-KEY'), "Content-Type": "application/json"}
ALL_LANGUAGES = ['Hindi', 'English', 'Bengali', 'Kannada', 'Spanish', 'French', 'German', 'Italian', 'Tamil', 'Telugu']
language_maps = {
"Hindi": "hi",
"English": "en",
"Spanish": "es",
"French": "fr",
"German": "de",
"Italian": "it",
"Tamil": "ta",
"Telugu": "te",
"Bengali": "bn",
"Kannada": "kn",
"hi": "Hindi",
"en": "English",
"es": "Spanish",
"fr": "French",
"de": "German",
"it": "Italian",
"ta": "Tamil",
"te": "Telugu",
"bn": "Bengali",
"kn": "Kannada"
}
def print_slack(platform, video_id, translator_name, assignment="translator"):
if platform == "dev":
return
else:
client = pymongo.MongoClient(os.environ.get("MONGO_URI"))
source_db = client.deepsync_prod
headers = {
'Content-type': 'application/json',
}
video = source_db.dubbedvideos.find_one({"_id": ObjectId(video_id)})
video_name = video['title']
source_language = language_maps[video['sourceLanguage'][:2]]
target_language = language_maps[video['targetLanguage'][:2]]
video_duration = str(timedelta(seconds=video['duration']))
translator_details = "/".join(translator_name.split("/")[:3])
message = f"""```{'Translator' if assignment == 'translator' else 'QA'} Assigned
Video Name : {video_name}
Source Language : {source_language}
Target Language : {target_language}
Video Duration : {video_duration} hours
Details : {translator_details}
```
"""
json_data = {
'text': message,
}
response = requests.post(
os.environ.get('SLACK_WEBHOOK'),
headers=headers,
json=json_data,
)
client.close()
def get_translators(platform):
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_DEV_URI"))
source_db = client.deepsync_stage
else:
api_url = "https://api.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_URI"))
source_db = client.deepsync_prod
response = requests.get(f"{api_url}/dashboard/translators", headers=HEADERS)
translators = list(filter(lambda x: not x.get('isDeleted', False), response.json()['data']))
translators_data = []
if len(translators):
desired_ids = [ObjectId(t["translator"]) for t in translators]
companies_cursor = source_db.companies.find({'_id': {'$in': desired_ids}})
companies = {c["_id"]: c for c in companies_cursor}
for translator in translators:
try:
data = companies[ObjectId(translator["translator"])]
translators_data.append({
"_id": str(translator["_id"]),
"Name": data["name"],
"Email": data["email"],
"Source Language": ", ".join(list(map(lambda x: language_maps[x], translator["sourceAccent"]))),
"Target Language": ", ".join(list(map(lambda x: language_maps[x], translator["targetAccent"])))
})
except Exception as e:
print(e)
pass
client.close()
return pd.DataFrame(translators_data)
def add_translator(platform, email_id, source_langs, target_langs, contact_num, pricing):
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_DEV_URI"))
source_db = client.deepsync_stage
else:
api_url = "https://api.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_URI"))
source_db = client.deepsync_prod
try:
company_id_validity = source_db.companies.find_one({"email": email_id})
except:
company_id_validity = None
if company_id_validity is None:
return "Invalid Company ID. Unable to add translator."
if source_langs is None:
source_accents = []
else:
source_accents = [language_maps[l] for l in source_langs]
if target_langs is None:
target_accents = []
else:
target_accents = [language_maps[l] for l in target_langs]
main_data = {
"targetAccent": target_accents,
"sourceAccent": source_accents,
"contactNum": None if len(contact_num.strip()) == 0 else contact_num.strip(),
"pricing": None if pricing is None or pricing == -1 else pricing
}
data = {"translator": str(company_id_validity["_id"]), **main_data}
response = requests.post(f"{api_url}/dashboard/translator", json=data, headers=HEADERS)
if str(response.status_code).startswith('4') or str(response.status_code).startswith('5'):
if response.json()['message'].strip() == "Translator already exists":
translator_main_id = source_db.translators.find_one({"translator": company_id_validity['_id']})
response = requests.patch(f"{api_url}/dashboard/translators/{translator_main_id['_id']}", json={"isDeleted": False, **main_data}, headers=HEADERS)
if str(response.status_code).startswith('4') or str(response.status_code).startswith('5'):
return f"{response.json()['message']} ({response.status_code})"
return f"Translator added succesfully, ID : {response.json()['data']['_id']}"
return f"{response.json()['message']} ({response.status_code})"
client.close()
return f"Translator added succesfully, ID : {response.json()['data']['_id']}"
def get_translator_names(platform):
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_DEV_URI"))
source_db = client.deepsync_stage
else:
api_url = "https://api.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_URI"))
source_db = client.deepsync_prod
response = requests.get(f"{api_url}/dashboard/translators", headers=HEADERS)
translators = list(filter(lambda x: not x.get('isDeleted', False), response.json()['data']))
translators_names = []
if len(translators):
desired_ids = [ObjectId(t["translator"]) for t in translators]
companies_cursor = source_db.companies.find({'_id': {'$in': desired_ids}})
companies = {c["_id"]: c for c in companies_cursor}
for translator in translators:
try:
data = companies[ObjectId(translator["translator"])]
translators_names.append(f'{data["name"]} / {data["email"]} / {translator["_id"]}')
except Exception as e:
print(e)
pass
client.close()
return gr.Dropdown.update(choices=translators_names)
def select_current_data(platform, translator_name):
if translator_name is None:
return "Please select a translator."
name, email, translator_id = list(map(lambda x: x.strip(), translator_name.split("/")))
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
response = requests.get(f"{api_url}/dashboard/translators", headers=HEADERS)
translators = list(filter(lambda x: not x.get('isDeleted', False) and x["_id"] == translator_id, response.json()['data']))
if len(translators):
translator = translators[0]
else:
raise Exception("Translator", translator_name, "not found.")
return gr.CheckboxGroup.update(value=[language_maps[l] for l in translator["sourceAccent"]]), gr.CheckboxGroup.update(value=[language_maps[l] for l in translator["targetAccent"]]), gr.Textbox.update(value="" if translator["contactNum"] is None else translator["contactNum"]), gr.Textbox.update(value=-1 if translator["pricing"] is None else translator["pricing"])
def update_translator(platform, translator_name, source_languages, target_languages, contact_num, pricing):
if translator_name is None:
return "Please select a translator."
name, email, translator_id = list(map(lambda x: x.strip(), translator_name.split("/")))
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
response = requests.get(f"{api_url}/dashboard/translators", headers=HEADERS)
translators = list(filter(lambda x: not x.get('isDeleted', False), response.json()['data']))
if len(translators):
translator = translators[0]
else:
raise Exception("Translator", translator_name, "not found.")
source_accents = [language_maps[l] for l in source_languages]
target_accents = [language_maps[l] for l in target_languages]
updateable_data = {
"sourceAccent": source_accents,
"targetAccent": target_accents,
"contactNum": "" if contact_num is None else contact_num.strip(),
"pricing": 0 if pricing is None else pricing
}
response = requests.patch(f"{api_url}/dashboard/translators/{translator_id}", json=updateable_data, headers=HEADERS)
if str(response.status_code).startswith('4') or str(response.status_code).startswith('5'):
return response.json()['message']
return f"Updated translator details succesfully."
def get_videos_under_review(platform, status_key):
status_keys = [status_key]
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
if status_keys is None or len(status_keys) == 0:
API_URL = f"{api_url}/dashboard/dubbed/videos/review/requested"
response = requests.get(API_URL, headers=HEADERS)
if response.status_code == 200:
options = [f"{str(v['_id'])} / {v['title']}" for v in response.json()['data'] if 'title' in v]
return gr.Dropdown.update(choices=options, value=None), ""
else:
return gr.Dropdown.update(choices=[], value=None), ""
else:
options = []
count = {}
for status in status_keys:
API_URL = f"{api_url}/dashboard/dubbed/videos/review/requested/{video_status[status]}"
response = requests.get(API_URL, headers=HEADERS)
if response.status_code == 200:
response_data = response.json()['data']
if status == "Not Assigned":
response_data = list(filter(lambda x: x["videoReviewInformation"].get("assignedTranslator") is None, response_data))
if status == "Under Review":
response_data = list(filter(lambda x: x["videoReviewInformation"].get("assignedTranslator") is not None, response_data))
current_options = [f"{str(v['_id'])} / {v['title']}" for v in response_data if 'title' in v]
count[status] = len(current_options)
options.extend(current_options)
data_text = "\n".join([f"{k} : {v} videos" for k,v in count.items()])
return gr.Dropdown.update(choices=options, value=None), data_text
def delete_translator_func(platform, translator_name):
if translator_name is None:
return "Please select a translator."
name, email, translator_id = list(map(lambda x: x.strip(), translator_name.split("/")))
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
response = requests.patch(f"{api_url}/dashboard/translators/{translator_id}", json={"isDeleted": True}, headers=HEADERS)
if str(response.status_code).startswith('4') or str(response.status_code).startswith('5'):
return response.json()['message']
return "Translator deleted."
def get_traslators_assign(platform, video):
video_id = video.split("/", maxsplit=1)[0].strip()
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_DEV_URI"))
source_db = client.deepsync_stage
else:
api_url = "https://api.deepsync.co/api/v1"
client = pymongo.MongoClient(os.environ.get("MONGO_URI"))
source_db = client.deepsync_prod
video = source_db.dubbedvideos.find_one({"_id": ObjectId(video_id)})
source_language = video["sourceLanguage"].split("-")[0]
target_language = video["targetLanguage"].split("-")[0]
translators = list(source_db.translators.find({"sourceAccent": {"$elemMatch": {"$eq": source_language}}, "targetAccent": {"$elemMatch": {"$eq": target_language}}}))
translators_list = []
pending_videos = []
for status in ["NOT_STARTED", "DUBBING_STARTED", "WAITING_QA"]:
API_URL = f"{api_url}/dashboard/dubbed/videos/review/requested/{status}"
response = requests.get(API_URL, headers=HEADERS)
if response.status_code == 200:
response_data = response.json()['data']
pending_videos.extend(response_data)
translator_pv_count = defaultdict(lambda: 0)
for pv in pending_videos:
if pv.get("videoReviewInformation", {}).get("assignedTranslator") is not None:
trs = str(pv.get("videoReviewInformation", {}).get("assignedTranslator"))
translator_pv_count[trs] += 1
if len(translators):
desired_ids = [t["translator"] for t in translators]
companies_cursor = source_db.companies.find({'_id': {'$in': desired_ids}})
companies = {c["_id"]: c for c in companies_cursor}
for translator in translators:
company = companies[translator["translator"]]
translators_list.append(f"{company['name']} / {company['email']} / {str(translator['_id'])} / Pending Videos: {translator_pv_count[str(translator['_id'])]}")
button = gr.Button.update(interactive=False)
current_translator = None
current_qa = None
if "videoReviewInformation" in video:
if video["videoReviewInformation"]["status"] in {"NOT_STARTED", "DUBBING_STARTED", "WAITING_QA"}:
button = gr.Button.update(interactive=True)
if video["videoReviewInformation"].get("assignedTranslator") is not None:
str_id = str(video["videoReviewInformation"].get("assignedTranslator"))
value = [v for v in translators_list if str_id in v]
current_translator = value[0] if len(value) else None
if video["videoReviewInformation"].get("assignedQA") is not None:
str_id = str(video["videoReviewInformation"].get("assignedQA"))
value = [v for v in translators_list if str_id in v]
current_qa = value[0] if len(value) else None
client.close()
return gr.Dropdown.update(choices=translators_list, value=current_translator), gr.Dropdown.update(choices=translators_list, value=current_qa), language_maps[source_language], language_maps[target_language], button, button
def assign_translator(platform, translator, video):
translator_id = translator.split("/")[2].strip()
video_id = video.split("/", maxsplit=1)[0].strip()
role = "translator"
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
data = {
"videoId": video_id,
"userId": translator_id
}
response = requests.post(f"{api_url}/dashboard/dubbed/video/assign/{role}", json=data, headers=HEADERS)
if str(response.status_code).startswith('2'):
print_slack(platform, video_id, translator, "translator")
return "Successfully assigned."
else:
return str(response.status_code)
def assign_qa(platform, qa, video):
translator_id = qa.split("/")[2].strip()
video_id = video.split("/", maxsplit=1)[0].strip()
role = "QA"
if platform == "dev":
api_url = "https://api.dev-env.deepsync.co/api/v1"
else:
api_url = "https://api.deepsync.co/api/v1"
data = {
"videoId": video_id,
"userId": translator_id
}
response = requests.post(f"{api_url}/dashboard/dubbed/video/assign/{role}", json=data, headers=HEADERS)
if str(response.status_code).startswith('2'):
print_slack(platform, video_id, qa, "qa")
return "Successfully assigned."
else:
return str(response.status_code)
with gr.Blocks() as demo:
gr.Markdown("# Translators Admin Dashboard")
with gr.Tab("List"):
source_platform = gr.Radio(["dev", "prod"], value="prod", label="Source Platform")
refresh_list = gr.Button("Load")
translators_list = gr.Dataframe(label="Translators", interactive=False, max_rows=20, overflow_row_behaviour="paginate")
with gr.Tab("Add"):
gr.Markdown("Add a new translator")
source_platform_add = gr.Radio(["dev", "prod"], value="prod", label="Source Platform")
email_id = gr.Textbox(label="Email ID", lines=1)
source_languages = gr.CheckboxGroup(ALL_LANGUAGES, label="Source Languages")
target_languages = gr.CheckboxGroup(ALL_LANGUAGES, label="Target Languages")
contact_num_box = gr.Textbox(label="Contact Number", lines=1)
pricing_box = gr.Number(label="Pricing", value=-1)
submit = gr.Button("Submit")
result = gr.Textbox(label="Logs")
with gr.Tab("Update"):
gr.Markdown("Update Translator")
source_platform_update = gr.Radio(["dev", "prod"], value="prod", label="Source Platform")
refresh_update_platform = gr.Button("Load")
translator_name = gr.Dropdown([], label="Translators")
source_languages_update = gr.CheckboxGroup(ALL_LANGUAGES, label="Source Languages")
target_languages_update = gr.CheckboxGroup(ALL_LANGUAGES, label="Target Languages")
contact_num_update = gr.Textbox(label="Contact Number", lines=1)
pricing_update = gr.Number(label="Pricing")
update_language = gr.Button("Update")
delete_translator = gr.Button("Delete Translator")
result_update = gr.Textbox(label="Logs")
with gr.Tab("Assign"):
gr.Markdown("Assign Translator / QA")
source_platform_assign = gr.Radio(["dev", "prod"], value="prod", label="Source Platform")
filter_videos_assign = gr.Radio(['Not Assigned', 'Under Review', 'Dubbing Started', 'Waiting QA', 'Sent to Client', 'Approved', 'Rejected', 'Churned', 'Re-review Requested'], label="Filter videos. Do not select any of them for videos without request info.")
video_details = gr.Textbox(label="Video Details")
refresh_assign = gr.Button("Load Videos")
under_review_videos_list = gr.Dropdown([], label="Video IDs")
with gr.Row():
source_language_box = gr.Textbox(label="Source Language")
target_language_box = gr.Textbox(label="Target Language")
with gr.Row():
translator_name_assign = gr.Dropdown([], label="Translator")
submit_tr_assign_button = gr.Button("Assign Translator")
with gr.Row():
qa_name_assign = gr.Dropdown([], label="QA")
submit_qa_assign_button = gr.Button("Assign QA")
assign_logs = gr.Textbox(label="Logs")
# For list
refresh_list.click(get_translators, source_platform, translators_list)
source_platform.change(get_translators, source_platform, translators_list)
# For add
submit.click(add_translator, [source_platform_add, email_id, source_languages, target_languages, contact_num_box, pricing_box], result)
# For Update
refresh_update_platform.click(get_translator_names, source_platform_update, translator_name)
source_platform_update.change(get_translator_names, source_platform_update, translator_name)
translator_name.change(select_current_data, [source_platform_update, translator_name], [source_languages_update, target_languages_update, contact_num_update, pricing_update])
update_language.click(update_translator, [source_platform_update, translator_name, source_languages_update, target_languages_update, contact_num_update, pricing_update], result_update)
delete_translator.click(delete_translator_func, [source_platform_update, translator_name], result_update)
# For Assign
refresh_assign.click(get_videos_under_review, [source_platform_assign, filter_videos_assign], [under_review_videos_list, video_details])
under_review_videos_list.change(get_traslators_assign, [source_platform_assign, under_review_videos_list], [translator_name_assign, qa_name_assign, source_language_box, target_language_box, submit_tr_assign_button, submit_qa_assign_button])
submit_tr_assign_button.click(assign_translator, [source_platform_assign, translator_name_assign, under_review_videos_list], assign_logs)
submit_qa_assign_button.click(assign_qa, [source_platform_assign, qa_name_assign, under_review_videos_list], assign_logs)
if __name__=="__main__":
demo.launch(auth=(os.environ.get("GRADIO_USERNAME"), os.environ.get("GRADIO_PASSWORD")))