(backend) accept conversion requests during analysis

Let a conversion be queued while the source is still analyzed; the real
conversion stays gated on READY in perform_conversion.
This commit is contained in:
Nicolas Clerc
2026-06-23 17:22:52 +02:00
parent 1dbcf31039
commit 3587826e1e
2 changed files with 33 additions and 3 deletions
+6 -3
View File
@@ -23,12 +23,15 @@ from wopi.conversion.source_url import build_source_url
MIME_SNIFF_BYTES = 2048
def _validate_conversion(item, user):
def _validate_conversion(item, user, require_ready=True):
"""Run pre-flight checks and return the target extension and client options."""
if item.type != models.ItemTypeChoices.FILE:
raise ConversionRejected("Source item is not a file.")
if item.upload_state != models.ItemUploadStateChoices.READY:
ready_states = [models.ItemUploadStateChoices.READY]
if not require_ready:
ready_states.append(models.ItemUploadStateChoices.ANALYZING)
if item.upload_state not in ready_states:
raise ConversionRejected("Source item is not ready.")
if not item.get_abilities(user).get("update"):
@@ -95,7 +98,7 @@ def prepare_conversion(source_item, user):
UI can display the converting state right away. The actual OnlyOffice
conversion happens later in a celery task.
"""
target_extension, _ = _validate_conversion(source_item, user)
target_extension, _ = _validate_conversion(source_item, user, require_ready=False)
parent = _resolve_destination_parent(source_item, user)
target_filename = _target_filename(source_item, target_extension, parent, user)
@@ -341,6 +341,33 @@ def test_prepare_conversion_returns_placeholder_in_converting_state(settings):
assert placeholder.parent().id == parent.id
def test_prepare_conversion_accepts_analyzing_source(settings):
"""Queue a conversion while the source is still being analyzed."""
_configure_wopi(settings)
user = factories.UserFactory()
item = _file(user, update_upload_state=models.ItemUploadStateChoices.ANALYZING)
placeholder = services.prepare_conversion(item, user)
assert placeholder.upload_state == models.ItemUploadStateChoices.CONVERTING
def test_perform_conversion_rejects_analyzing_source(settings):
"""Never convert the bytes before analysis confirmed the source is safe."""
_configure_wopi(settings)
user = factories.UserFactory()
item = _file(user, update_upload_state=models.ItemUploadStateChoices.ANALYZING)
placeholder = factories.ItemFactory(
users=[(user, models.RoleChoices.EDITOR)],
type=models.ItemTypeChoices.FILE,
filename="document.docx",
update_upload_state=models.ItemUploadStateChoices.CONVERTING,
)
with pytest.raises(exceptions.ConversionRejected, match="not ready"):
services.perform_conversion(item, placeholder, user)
def test_prepare_conversion_rejects_unsupported_extensions(settings):
"""Skip placeholder creation for files that cannot be converted."""
_configure_wopi(settings)