Extend submission config: .mxf/codec/frame-rate checks, regex naming, shot/asset tabs
- Movie spec checks now also cover codec (h264/h265/mjpeg/dnxhd/dnxhr/
prores/uncompressed/avid/cineform) and frame rate (23.976/24/30/48/60),
detected in-browser via mediainfo.js container parsing - works even
for formats the native <video> element can't decode (MXF, ProRes,
DNxHD). Added .mxf to the supported/allowed format lists.
- Naming pattern supports a raw regex mode (validated by compiling
server-side at save time) as an alternative to the token pattern,
and gained three more tokens: {task_name}, {project_name},
{project_code} (fetched lazily only when referenced).
- Submission Configuration settings page now splits Shot Tasks /
Asset Tasks into separate tabs instead of one merged list; the
per-task-type card was extracted into SubmissionTypeConfigCard.vue
to avoid duplicating it across both tabs.
This commit is contained in:
@@ -7,8 +7,8 @@ import re
|
||||
|
||||
from utils.file_handler import file_handler
|
||||
|
||||
# Tokens supported in a naming_pattern: {name} (shot/asset name), {task_type}, {version}
|
||||
NAMING_PATTERN_TOKEN_RE = re.compile(r'\{(name|task_type|version)\}')
|
||||
# Tokens supported in a token-mode naming_pattern
|
||||
NAMING_PATTERN_TOKEN_RE = re.compile(r'\{(name|task_type|task_name|project_name|project_code|version)\}')
|
||||
NAMING_PATTERN_ALLOWED_CHARS_RE = re.compile(r'^[A-Za-z0-9_\-\.]*$')
|
||||
|
||||
|
||||
@@ -26,7 +26,12 @@ class SubmissionTypeConfig(BaseModel):
|
||||
itself, it is never used to inspect an uploaded file server-side.
|
||||
"""
|
||||
allowed_extensions: List[str] = Field(default_factory=list, description="Accepted file extensions, e.g. ['.mov', '.exr']")
|
||||
naming_pattern: Optional[str] = Field(None, description="Filename pattern using {name}, {task_type}, {version} tokens")
|
||||
naming_pattern_is_regex: bool = Field(False, description="If true, naming_pattern is a raw regular expression instead of a token pattern")
|
||||
naming_pattern: Optional[str] = Field(
|
||||
None,
|
||||
description="Either a token pattern (using {name}, {task_type}, {task_name}, {project_name}, "
|
||||
"{project_code}, {version}) or, if naming_pattern_is_regex is set, a raw regular expression"
|
||||
)
|
||||
check_naming: bool = Field(True, description="Whether the naming pattern is actively checked")
|
||||
required: bool = Field(False, description="Whether a submission is expected for this task type (informational only)")
|
||||
check_movie_spec: bool = Field(False, description="Whether to check video submissions against movie_resolution/movie_format/movie_codec/movie_frame_rate")
|
||||
@@ -51,15 +56,21 @@ class SubmissionTypeConfig(BaseModel):
|
||||
return normalized
|
||||
|
||||
@validator('naming_pattern')
|
||||
def validate_naming_pattern(cls, v):
|
||||
def validate_naming_pattern(cls, v, values):
|
||||
if v is None or v == '':
|
||||
return None
|
||||
# Strip out known tokens, then everything left must be safe literal characters
|
||||
if values.get('naming_pattern_is_regex'):
|
||||
try:
|
||||
re.compile(v)
|
||||
except re.error as e:
|
||||
raise ValueError(f'Invalid regular expression: {e}')
|
||||
return v
|
||||
# Token mode: strip out known tokens, then everything left must be safe literal characters
|
||||
stripped = NAMING_PATTERN_TOKEN_RE.sub('', v)
|
||||
if not NAMING_PATTERN_ALLOWED_CHARS_RE.match(stripped):
|
||||
raise ValueError(
|
||||
'Naming pattern may only contain letters, numbers, "_", "-", "." '
|
||||
'and the tokens {name}, {task_type}, {version}'
|
||||
'and the tokens {name}, {task_type}, {task_name}, {project_name}, {project_code}, {version}'
|
||||
)
|
||||
return v
|
||||
|
||||
|
||||
Reference in New Issue
Block a user