Skip to content

publish_plugins

CollectUSDLayerContributionsProfileModel

Bases: BaseSettingsModel

Profiles to define instance attribute defaults for USD contribution.

Source code in server/settings/publish_plugins.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
class CollectUSDLayerContributionsProfileModel(BaseSettingsModel):
    """Profiles to define instance attribute defaults for USD contribution."""
    _layout = "expanded"
    product_base_types: list[str] = SettingsField(
        default_factory=list,
        title="Product base types",
        description=(
            "The product base types to match this profile to. When matched,"
            " the settings below would apply to the instance as default"
            " attributes."
        ),
        section="Filter"
    )
    task_types: list[str] = SettingsField(
        default_factory=list,
        title="Task Types",
        enum_resolver=task_types_enum,
        description=(
            "The current create context task type to filter against. This"
            " allows to filter the profile to only be valid if currently "
            " creating from within that task type."
        ),
    )
    task_names: list[str] = SettingsField(
        default_factory=list,
        title="Task names",
    )
    contribution_enabled: bool = SettingsField(
        True,
        title="Contribution Enabled (default)",
        description=(
            "The default state for USD Contribution being marked enabled or"
            " disabled for this profile."
        ),
        section="Instance attribute defaults",
    )
    contribution_layer: str = SettingsField(
        "",
        title="Contribution Department Layer",
        description=(
            "The default contribution layer to apply the contribution to when"
            " matching this profile. The layer name should be in the"
            " 'Department Layer Orders' list to get a sensible order."
        ),
    )
    contribution_target_product: str = SettingsField(
        "usdAsset",
        title="Target Product",
        description=(
            "The default destination product name to apply the contribution to"
            " when matching this profile."
            " Usually e.g. 'usdAsset' or 'usdShot'."
        ),
    )
    contribution_apply_as_variant: bool = SettingsField(
        True,
        title="Apply as variant",
        description=(
            "The default 'Apply as variant' state for instances matching this"
            " profile. Usually enabled for asset contributions and disabled"
            " for shot contributions."
        ),
    )
    contribution_variant_set_name: str = SettingsField(
        "{layer}",
        title="Variant Set name",
        description=(
            "The default variant set name for instances matching this profile."
        ),
    )
    contribution_variant: str = SettingsField(
        "{variant}",
        title="Variant Name",
        description=(
            "The default variant name for instances matching this profile."
        ),
    )
    contribution_variant_is_default: bool = SettingsField(
        False,
        title="Set as default variant selection",
        description=(
            "Whether to set this instance's variant name as the "
            "default selected variant name for the variant set.\n"
            "It is always expected to be enabled for only one "
            "variant name in the variant set.\n"
            "The behavior is unpredictable if multiple instances "
            "for the same variant set have this enabled."
        ),
    )

EntityListFolderModel

Bases: BaseSettingsModel

Folder must have label and can be scoped to views.

Scope of the folder can be defined for all views or use just the view matching list type of created list. In case the list folder already exists the settings are not used and we just make sure the list can be seen under the folder.

Source code in server/settings/publish_plugins.py
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
class EntityListFolderModel(BaseSettingsModel):
    """Folder must have label and can be scoped to views.

    Scope of the folder can be defined for all views or use just the view
        matching list type of created list. In case the list folder already
        exists the settings are not used and we just make sure the list can
        be seen under the folder.

    """
    _layout = "expanded"
    label: str = SettingsField(
        "",
        title="Folder label",
        description=(
            "The label of the folder to create. "
            "Anatomy formattable template for the name."
        ),
    )
    # Don't use explicit scope enum, rather ask if the folder should be seen
    #   everywhere or just in the list type matching created list.
    scope_def: str = SettingsField(
        "all",
        enum_resolver=list_folder_scope_def,
        title="Scope",
    )

ExtractBurninDef

Bases: BaseSettingsModel

Source code in server/settings/publish_plugins.py
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
class ExtractBurninDef(BaseSettingsModel):
    _isGroup = True
    _layout = "expanded"
    name: str = SettingsField("")
    TOP_LEFT: str = SettingsField("", title="Top Left")
    TOP_CENTERED: str = SettingsField("", title="Top Centered")
    TOP_RIGHT: str = SettingsField("", title="Top Right")
    BOTTOM_LEFT: str = SettingsField("", title="Bottom Left")
    BOTTOM_CENTERED: str = SettingsField("", title="Bottom Centered")
    BOTTOM_RIGHT: str = SettingsField("", title="Bottom Right")
    filter: ExtractBurninDefFilter = SettingsField(
        default_factory=ExtractBurninDefFilter,
        title="Additional filtering"
    )

    @validator("name")
    def validate_name(cls, value):
        """Ensure name does not contain weird characters"""
        return normalize_name(value)

validate_name(value)

Ensure name does not contain weird characters

Source code in server/settings/publish_plugins.py
1170
1171
1172
1173
@validator("name")
def validate_name(cls, value):
    """Ensure name does not contain weird characters"""
    return normalize_name(value)

ExtractOIIOPostProcessModel

Bases: BaseSettingsModel

Process representation images with oiiotool on publish.

This could be used to convert images to different formats, convert to scanline images or flatten deep images.

Source code in server/settings/publish_plugins.py
911
912
913
914
915
916
917
918
919
920
class ExtractOIIOPostProcessModel(BaseSettingsModel):
    """Process representation images with `oiiotool` on publish.

    This could be used to convert images to different formats, convert to
    scanline images or flatten deep images.
    """
    enabled: bool = SettingsField(True)
    profiles: list[ExtractOIIOPostProcessProfileModel] = SettingsField(
        default_factory=list, title="Profiles"
    )

ExtractOIIOTranscodeModel

Bases: BaseSettingsModel

Color conversion transcoding using OIIO for images mostly aimed at transcoding for reviewables (it'll process and output only RGBA channels).

Source code in server/settings/publish_plugins.py
803
804
805
806
807
808
809
810
class ExtractOIIOTranscodeModel(BaseSettingsModel):
    """Color conversion transcoding using OIIO for images mostly aimed at
    transcoding for reviewables (it'll process and output only RGBA channels).
    """
    enabled: bool = SettingsField(True)
    profiles: list[ExtractOIIOTranscodeProfileModel] = SettingsField(
        default_factory=list, title="Profiles"
    )

ExtractReviewOutputDefModel

Bases: BaseSettingsModel

Source code in server/settings/publish_plugins.py
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
class ExtractReviewOutputDefModel(BaseSettingsModel):
    _layout = "expanded"
    name: str = SettingsField("", title="Name")
    ext: str = SettingsField("", title="Output extension")
    # TODO use some different source of tags
    tags: list[str] = SettingsField(default_factory=list, title="Tags")
    burnins: list[str] = SettingsField(
        default_factory=list, title="Link to a burnin by name"
    )
    ffmpeg_args: ExtractReviewFFmpegModel = SettingsField(
        default_factory=ExtractReviewFFmpegModel,
        title="FFmpeg arguments"
    )
    filter: ExtractReviewFilterModel = SettingsField(
        default_factory=ExtractReviewFilterModel,
        title="Additional output filtering"
    )
    overscan_crop: str = SettingsField(
        "",
        title="Overscan crop",
        description=(
            "Crop input overscan. See the documentation for more information."
        )
    )
    overscan_color: ColorRGBA_uint8 = SettingsField(
        (0, 0, 0, 0.0),
        title="Overscan color",
        description=(
            "Overscan color is used when input aspect ratio is not"
            " same as output aspect ratio."
        )
    )
    # overscan_color: ColorRGB_uint8 = SettingsField(
    #     (0, 0, 0),
    #     title="Overscan color",
    #     description=(
    #         "Overscan color is used when input aspect ratio is not"
    #         " same as output aspect ratio."
    #     )
    # )
    width: int = SettingsField(
        0,
        ge=0,
        le=100000,
        title="Output width",
        description=(
            "Width and Height must be both set to higher"
            " value than 0 else source resolution is used."
        )
    )
    height: int = SettingsField(
        0,
        title="Output height",
        ge=0,
        le=100000,
    )
    scale_pixel_aspect: bool = SettingsField(
        True,
        title="Scale pixel aspect",
        description=(
            "Rescale input when it's pixel aspect ratio is not 1."
            " Useful for anamorphic reviews."
        )
    )
    bg_color: ColorRGBA_uint8 = SettingsField(
        (0, 0, 0, 0.0),
        description=(
            "Background color is used only when input have transparency"
            " and Alpha is higher than 0."
        ),
        title="Background color",
    )
    letter_box: ExtractReviewLetterBox = SettingsField(
        default_factory=ExtractReviewLetterBox,
        title="Letter Box"
    )
    fill_missing_frames: str = SettingsField(
        title="Handle missing frames",
        default="closest_existing",
        description="How to handle gaps in sequence frame ranges.",
        enum_resolver=_handle_missing_frames_enum
    )

    @validator("name")
    def validate_name(cls, value):
        """Ensure name does not contain weird characters"""
        return normalize_name(value)

validate_name(value)

Ensure name does not contain weird characters

Source code in server/settings/publish_plugins.py
1084
1085
1086
1087
@validator("name")
def validate_name(cls, value):
    """Ensure name does not contain weird characters"""
    return normalize_name(value)

ExtractThumbnailFromSourceModel

Bases: BaseSettingsModel

Thumbnail extraction from source files using ffmpeg and oiiotool.

Source code in server/settings/publish_plugins.py
676
677
678
679
680
681
682
683
684
685
class ExtractThumbnailFromSourceModel(BaseSettingsModel):
    """Thumbnail extraction from source files using ffmpeg and oiiotool."""
    enabled: bool = SettingsField(True)

    target_size: ResizeModel = SettingsField(
        default_factory=ResizeModel, title="Target size"
    )
    background_color: ColorRGBA_uint8 = SettingsField(
        (0, 0, 0, 0.0), title="Background color"
    )

IntegrateProductGroupModel

Bases: BaseSettingsModel

Group published products by filtering logic.

Set all published instances as a part of specific group named according to 'Template'.

Implemented all variants of placeholders '{task}', '{product[type]}', '{host}', '{product[name]}', '{renderlayer}'.

Source code in server/settings/publish_plugins.py
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
class IntegrateProductGroupModel(BaseSettingsModel):
    """Group published products by filtering logic.

    Set all published instances as a part of specific group named according
     to 'Template'.

    Implemented all variants of placeholders '{task}', '{product[type]}',
    '{host}', '{product[name]}', '{renderlayer}'.
    """

    _isGroup = True
    product_grouping_profiles: list[IntegrateProductGroupProfile] = (
        SettingsField(
            default_factory=list,
            title="Product group profiles"
        )
    )

PreIntegrateThumbnailsModel

Bases: BaseSettingsModel

Explicitly set if Thumbnail representation should be integrated.

If no matching profile set, existing state from Host implementation is kept.

Source code in server/settings/publish_plugins.py
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
class PreIntegrateThumbnailsModel(BaseSettingsModel):
    """Explicitly set if Thumbnail representation should be integrated.

    If no matching profile set, existing state from Host implementation
    is kept.
    """

    _isGroup = True
    enabled: bool = SettingsField(True)
    integrate_profiles: list[PreIntegrateThumbnailsProfile] = SettingsField(
        default_factory=list,
        title="Integrate profiles"
    )

ValidateIntentModel

Bases: BaseSettingsModel

Validate if Publishing intent was selected.

It is possible to disable validation for specific publishing context with profiles.

Source code in server/settings/publish_plugins.py
489
490
491
492
493
494
495
496
497
498
class ValidateIntentModel(BaseSettingsModel):
    """Validate if Publishing intent was selected.

    It is possible to disable validation for specific publishing context
    with profiles.
    """

    _isGroup = True
    enabled: bool = SettingsField(False)
    profiles: list[ValidateIntentProfile] = SettingsField(default_factory=list)

ensure_unique_resolution_option(objects, field_name=None)

Ensure a list of objects have unique option attributes.

This function checks if the list of objects has unique 'width', 'height' and 'pixel_aspect' properties.

Source code in server/settings/publish_plugins.py
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
def ensure_unique_resolution_option(
        objects: list[Any], field_name: str | None = None) -> None:  # noqa: C901
    """Ensure a list of objects have unique option attributes.

    This function checks if the list of objects has unique 'width',
    'height' and 'pixel_aspect' properties.
    """
    options = set()
    for obj in objects:
        item_test_text = f"{obj.width}x{obj.height}x{obj.pixel_aspect}"
        if item_test_text in options:
            raise BadRequestException(
                f"Duplicate option '{item_test_text}'")

        options.add(item_test_text)