feat: add waveform voice messages end-to-end
All checks were successful
CI / test (push) Successful in 23s
All checks were successful
CI / test (push) Successful in 23s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import mimetypes
|
||||
import json
|
||||
from urllib.parse import quote
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -29,6 +30,35 @@ ALLOWED_MIME_TYPES = {
|
||||
"text/plain",
|
||||
}
|
||||
|
||||
|
||||
def _normalize_waveform(points: list[int] | None) -> list[int] | None:
|
||||
if points is None:
|
||||
return None
|
||||
normalized = [max(0, min(31, int(value))) for value in points]
|
||||
if len(normalized) < 8:
|
||||
return None
|
||||
return normalized
|
||||
|
||||
|
||||
def _decode_waveform(raw: str | None) -> list[int] | None:
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
parsed = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
if not isinstance(parsed, list):
|
||||
return None
|
||||
result: list[int] = []
|
||||
for value in parsed[:256]:
|
||||
if isinstance(value, int):
|
||||
result.append(max(0, min(31, value)))
|
||||
elif isinstance(value, float):
|
||||
result.append(max(0, min(31, int(value))))
|
||||
else:
|
||||
return None
|
||||
return result or None
|
||||
|
||||
def _normalize_mime(file_type: str) -> str:
|
||||
return file_type.split(";", maxsplit=1)[0].strip().lower()
|
||||
|
||||
@@ -125,16 +155,27 @@ async def store_attachment_metadata(
|
||||
detail="Only the message sender can attach files",
|
||||
)
|
||||
|
||||
normalized_waveform = _normalize_waveform(payload.waveform_points)
|
||||
attachment = await repository.create_attachment(
|
||||
db,
|
||||
message_id=payload.message_id,
|
||||
file_url=payload.file_url,
|
||||
file_type=payload.file_type,
|
||||
file_size=payload.file_size,
|
||||
waveform_data=json.dumps(normalized_waveform, ensure_ascii=True) if normalized_waveform else None,
|
||||
)
|
||||
await db.commit()
|
||||
await db.refresh(attachment)
|
||||
return AttachmentRead.model_validate(attachment)
|
||||
return AttachmentRead.model_validate(
|
||||
{
|
||||
"id": attachment.id,
|
||||
"message_id": attachment.message_id,
|
||||
"file_url": attachment.file_url,
|
||||
"file_type": attachment.file_type,
|
||||
"file_size": attachment.file_size,
|
||||
"waveform_points": _decode_waveform(attachment.waveform_data),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def list_attachments_for_chat(
|
||||
@@ -162,6 +203,7 @@ async def list_attachments_for_chat(
|
||||
file_url=attachment.file_url,
|
||||
file_type=attachment.file_type,
|
||||
file_size=attachment.file_size,
|
||||
waveform_points=_decode_waveform(attachment.waveform_data),
|
||||
)
|
||||
for attachment, message in rows
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user