diff --git a/backend/schemas/submission_config.py b/backend/schemas/submission_config.py
index 8f83451..c5c0ed9 100644
--- a/backend/schemas/submission_config.py
+++ b/backend/schemas/submission_config.py
@@ -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
diff --git a/frontend/src/components/project/SubmissionConfigManager.vue b/frontend/src/components/project/SubmissionConfigManager.vue
index 39de198..3f32540 100644
--- a/frontend/src/components/project/SubmissionConfigManager.vue
+++ b/frontend/src/components/project/SubmissionConfigManager.vue
@@ -11,132 +11,36 @@
Loading submission configuration...
-