✨(summary) link transcript to their downloadable recording
Link the transcription document to its related recording by adding a short header explaining that users can download the audio file via a dedicated link. This was a highly requested feature, as many users need to keep their audio files. As part of a small refactor, remove the argument length check in the metadata analytics class. The hardcoded argument count made code evolution harder and was easy to forget updating. Argument unwrapping remains fragile and should be redesigned later to be more robust. The backend is responsible for generating the download link to ensure consistency and reliability. I tried adding a divider, but the Markdown-to-Yjs conversion is very lossy and almost never handles it correctly. Only about one out of ten conversions works as expected.
This commit is contained in:
committed by
aleb_the_flash
parent
f7b45622bc
commit
39271544d7
@@ -63,7 +63,7 @@ RECORDING_STORAGE_EVENT_ENABLE=True
|
||||
RECORDING_STORAGE_EVENT_TOKEN=password
|
||||
SUMMARY_SERVICE_ENDPOINT=http://app-summary-dev:8000/api/v1/tasks/
|
||||
SUMMARY_SERVICE_API_TOKEN=password
|
||||
SCREEN_RECORDING_BASE_URL=http://localhost:3000/recordings
|
||||
RECORDING_DOWNLOAD_BASE_URL=http://localhost:3000/recording
|
||||
|
||||
# Telephony
|
||||
ROOM_TELEPHONY_ENABLED=True
|
||||
|
||||
@@ -16,6 +16,23 @@ from core import models
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_recording_download_base_url() -> str:
|
||||
"""Get the recording download base URL with backward compatibility."""
|
||||
new_setting = settings.RECORDING_DOWNLOAD_BASE_URL
|
||||
old_setting = settings.SCREEN_RECORDING_BASE_URL
|
||||
|
||||
if old_setting:
|
||||
logger.warning(
|
||||
"SCREEN_RECORDING_BASE_URL is deprecated and will be removed in a future version. "
|
||||
"Please use RECORDING_DOWNLOAD_BASE_URL instead."
|
||||
)
|
||||
|
||||
if new_setting:
|
||||
return new_setting
|
||||
|
||||
return old_setting
|
||||
|
||||
|
||||
class NotificationService:
|
||||
"""Service for processing recordings and notifying external services."""
|
||||
|
||||
@@ -69,7 +86,7 @@ class NotificationService:
|
||||
"domain": settings.EMAIL_DOMAIN,
|
||||
"room_name": recording.room.name,
|
||||
"recording_expiration_days": settings.RECORDING_EXPIRATION_DAYS,
|
||||
"link": f"{settings.SCREEN_RECORDING_BASE_URL}/{recording.id}",
|
||||
"link": f"{get_recording_download_base_url()}/{recording.id}",
|
||||
}
|
||||
|
||||
has_failures = False
|
||||
@@ -149,6 +166,7 @@ class NotificationService:
|
||||
"recording_time": recording.created_at.astimezone(
|
||||
owner_access.user.timezone
|
||||
).strftime("%H:%M"),
|
||||
"download_link": f"{get_recording_download_base_url()}/{recording.id}",
|
||||
}
|
||||
|
||||
headers = {
|
||||
|
||||
@@ -634,6 +634,9 @@ class Base(Configuration):
|
||||
SCREEN_RECORDING_BASE_URL = values.Value(
|
||||
None, environ_name="SCREEN_RECORDING_BASE_URL", environ_prefix=None
|
||||
)
|
||||
RECORDING_DOWNLOAD_BASE_URL = values.Value(
|
||||
None, environ_name="RECORDING_DOWNLOAD_BASE_URL", environ_prefix=None
|
||||
)
|
||||
|
||||
# Marketing and communication settings
|
||||
SIGNUP_NEW_USER_TO_MARKETING_EMAIL = values.BooleanValue(
|
||||
|
||||
@@ -67,7 +67,7 @@ backend:
|
||||
RECORDING_STORAGE_EVENT_TOKEN: password
|
||||
SUMMARY_SERVICE_ENDPOINT: http://meet-summary:80/api/v1/tasks/
|
||||
SUMMARY_SERVICE_API_TOKEN: password
|
||||
SCREEN_RECORDING_BASE_URL: https://meet.127.0.0.1.nip.io/recordings
|
||||
RECORDING_DOWNLOAD_BASE_URL: https://meet.127.0.0.1.nip.io/recording
|
||||
ROOM_TELEPHONY_ENABLED: True
|
||||
SSL_CERT_FILE: /usr/local/lib/python3.12/site-packages/certifi/cacert.pem
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ backend:
|
||||
RECORDING_STORAGE_EVENT_TOKEN: password
|
||||
SUMMARY_SERVICE_ENDPOINT: http://meet-summary:80/api/v1/tasks/
|
||||
SUMMARY_SERVICE_API_TOKEN: password
|
||||
SCREEN_RECORDING_BASE_URL: https://meet.127.0.0.1.nip.io/recordings
|
||||
RECORDING_DOWNLOAD_BASE_URL: https://meet.127.0.0.1.nip.io/recording
|
||||
ROOM_TELEPHONY_ENABLED: True
|
||||
ROOM_TELEPHONY_DEFAULT_COUNTRY: 'FR'
|
||||
ROOM_TELEPHONY_PHONE_NUMBER: '+33901020304'
|
||||
|
||||
@@ -84,7 +84,7 @@ backend:
|
||||
RECORDING_STORAGE_EVENT_TOKEN: password
|
||||
SUMMARY_SERVICE_ENDPOINT: http://meet-summary:80/api/v1/tasks/
|
||||
SUMMARY_SERVICE_API_TOKEN: password
|
||||
SCREEN_RECORDING_BASE_URL: https://meet.127.0.0.1.nip.io/recordings
|
||||
RECORDING_DOWNLOAD_BASE_URL: https://meet.127.0.0.1.nip.io/recording
|
||||
SIGNUP_NEW_USER_TO_MARKETING_EMAIL: True
|
||||
BREVO_API_KEY:
|
||||
secretKeyRef:
|
||||
|
||||
@@ -27,6 +27,7 @@ class TaskCreation(BaseModel):
|
||||
recording_date: Optional[str]
|
||||
recording_time: Optional[str]
|
||||
language: Optional[str]
|
||||
download_link: Optional[str]
|
||||
|
||||
@field_validator("language")
|
||||
@classmethod
|
||||
@@ -57,6 +58,7 @@ async def create_task(request: TaskCreation):
|
||||
request.recording_date,
|
||||
request.recording_time,
|
||||
request.language,
|
||||
request.download_link,
|
||||
],
|
||||
queue=settings.transcribe_queue,
|
||||
)
|
||||
|
||||
@@ -118,11 +118,6 @@ class MetadataManager:
|
||||
"retries": 0,
|
||||
}
|
||||
|
||||
_required_args_count = 9
|
||||
if len(task_args) != _required_args_count:
|
||||
logger.error("Invalid number of arguments to enable metadata manager.")
|
||||
return
|
||||
|
||||
_, filename, email, _, received_at, *_ = task_args
|
||||
|
||||
initial_metadata = {
|
||||
|
||||
@@ -120,6 +120,7 @@ def process_audio_transcribe_summarize_v2(
|
||||
recording_date: Optional[str],
|
||||
recording_time: Optional[str],
|
||||
language: Optional[str],
|
||||
download_link: Optional[str],
|
||||
):
|
||||
"""Process an audio file by transcribing it and generating a summary.
|
||||
|
||||
@@ -184,6 +185,7 @@ def process_audio_transcribe_summarize_v2(
|
||||
room=room,
|
||||
recording_date=recording_date,
|
||||
recording_time=recording_time,
|
||||
download_link=download_link,
|
||||
)
|
||||
|
||||
data = {
|
||||
|
||||
@@ -65,6 +65,7 @@ class TranscriptFormatter:
|
||||
room: Optional[str] = None,
|
||||
recording_date: Optional[str] = None,
|
||||
recording_time: Optional[str] = None,
|
||||
download_link: Optional[str] = None,
|
||||
) -> Tuple[str, str]:
|
||||
"""Format transcription into the final document and its title."""
|
||||
segments = self._get_segments(transcription)
|
||||
@@ -74,6 +75,7 @@ class TranscriptFormatter:
|
||||
else:
|
||||
content = self._format_speaker(segments)
|
||||
content = self._remove_hallucinations(content)
|
||||
content = self._add_header(content, download_link)
|
||||
|
||||
title = self._generate_title(room, recording_date, recording_time)
|
||||
|
||||
@@ -104,6 +106,19 @@ class TranscriptFormatter:
|
||||
|
||||
return formatted_output
|
||||
|
||||
def _add_header(self, content, download_link: Optional[str]) -> str:
|
||||
"""Add download link header to the document content."""
|
||||
if not download_link:
|
||||
return content
|
||||
|
||||
header = (
|
||||
f"\n*Télécharger votre enregistrement "
|
||||
f"en [suivant ce lien]({download_link})*\n"
|
||||
)
|
||||
content = header + content
|
||||
|
||||
return content
|
||||
|
||||
def _generate_title(
|
||||
self,
|
||||
room: Optional[str] = None,
|
||||
|
||||
Reference in New Issue
Block a user