diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py index ababb01285..4cb510f1cb 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py @@ -15,11 +15,11 @@ from ayon_core.pipeline.publish.lib import ( replace_with_published_scene_path ) from ayon_core.pipeline.publish import KnownPublishError -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api.lib import ( get_current_renderer, get_multipass_setting ) -from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings +from ayon_max.api.lib_rendersettings import RenderSettings from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo @@ -205,11 +205,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, def _use_published_name(self, data, project_settings): # Not all hosts can import these modules. - from ayon_core.hosts.max.api.lib import ( + from ayon_max.api.lib import ( get_current_renderer, get_multipass_setting ) - from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings + from ayon_max.api.lib_rendersettings import RenderSettings instance = self._instance job_info = copy.deepcopy(self.job_info) diff --git a/client/ayon_core/plugins/publish/validate_version.py b/client/ayon_core/plugins/publish/validate_version.py index 25a5757330..c2f7d5bf44 100644 --- a/client/ayon_core/plugins/publish/validate_version.py +++ b/client/ayon_core/plugins/publish/validate_version.py @@ -1,6 +1,10 @@ import pyblish.api + +from ayon_core.lib import filter_profiles from ayon_core.pipeline.publish import ( - PublishValidationError, OptionalPyblishPluginMixin + PublishValidationError, + OptionalPyblishPluginMixin, + get_current_host_name, ) @@ -13,12 +17,35 @@ class ValidateVersion(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): order = pyblish.api.ValidatorOrder label = "Validate Version" - hosts = ["nuke", "maya", "houdini", "blender", - "photoshop", "aftereffects"] optional = False active = True + @classmethod + def apply_settings(cls, settings): + # Disable if no profile is found for the current host + profiles = ( + settings + ["core"] + ["publish"] + ["ValidateVersion"] + ["plugin_state_profiles"] + ) + profile = filter_profiles( + profiles, {"host_names": get_current_host_name()} + ) + if not profile: + cls.enabled = False + return + + # Apply settings from profile + for attr_name in { + "enabled", + "optional", + "active", + }: + setattr(cls, attr_name, profile[attr_name]) + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/tools/common_models/__init__.py b/client/ayon_core/tools/common_models/__init__.py index 8895515b1a..f09edfeab2 100644 --- a/client/ayon_core/tools/common_models/__init__.py +++ b/client/ayon_core/tools/common_models/__init__.py @@ -14,6 +14,7 @@ from .hierarchy import ( ) from .thumbnails import ThumbnailsModel from .selection import HierarchyExpectedSelection +from .users import UsersModel __all__ = ( @@ -32,4 +33,6 @@ __all__ = ( "ThumbnailsModel", "HierarchyExpectedSelection", + + "UsersModel", ) diff --git a/client/ayon_core/tools/common_models/users.py b/client/ayon_core/tools/common_models/users.py new file mode 100644 index 0000000000..f8beb31aa1 --- /dev/null +++ b/client/ayon_core/tools/common_models/users.py @@ -0,0 +1,84 @@ +import ayon_api + +from ayon_core.lib import CacheItem + + +class UserItem: + def __init__( + self, + username, + full_name, + email, + avatar_url, + active, + ): + self.username = username + self.full_name = full_name + self.email = email + self.avatar_url = avatar_url + self.active = active + + @classmethod + def from_entity_data(cls, user_data): + return cls( + user_data["name"], + user_data["attrib"]["fullName"], + user_data["attrib"]["email"], + user_data["attrib"]["avatarUrl"], + user_data["active"], + ) + + +class UsersModel: + def __init__(self, controller): + self._controller = controller + self._users_cache = CacheItem(default_factory=list) + + def get_user_items(self): + """Get user items. + + Returns: + List[UserItem]: List of user items. + + """ + self._invalidate_cache() + return self._users_cache.get_data() + + def get_user_items_by_name(self): + """Get user items by name. + + Implemented as most of cases using this model will need to find + user information by username. + + Returns: + Dict[str, UserItem]: Dictionary of user items by name. + + """ + return { + user_item.username: user_item + for user_item in self.get_user_items() + } + + def get_user_item_by_username(self, username): + """Get user item by username. + + Args: + username (str): Username. + + Returns: + Union[UserItem, None]: User item or None if not found. + + """ + self._invalidate_cache() + for user_item in self.get_user_items(): + if user_item.username == username: + return user_item + return None + + def _invalidate_cache(self): + if self._users_cache.is_valid: + return + self._users_cache.update_data([ + UserItem.from_entity_data(user) + for user in ayon_api.get_users() + ]) diff --git a/client/ayon_core/tools/workfiles/abstract.py b/client/ayon_core/tools/workfiles/abstract.py index c9eb9004e3..f345e20dca 100644 --- a/client/ayon_core/tools/workfiles/abstract.py +++ b/client/ayon_core/tools/workfiles/abstract.py @@ -13,8 +13,10 @@ class WorkfileInfo: task_id (str): Task id. filepath (str): Filepath. filesize (int): File size. - creation_time (int): Creation time (timestamp). - modification_time (int): Modification time (timestamp). + creation_time (float): Creation time (timestamp). + modification_time (float): Modification time (timestamp). + created_by (Union[str, none]): User who created the file. + updated_by (Union[str, none]): User who last updated the file. note (str): Note. """ @@ -26,6 +28,8 @@ class WorkfileInfo: filesize, creation_time, modification_time, + created_by, + updated_by, note, ): self.folder_id = folder_id @@ -34,6 +38,8 @@ class WorkfileInfo: self.filesize = filesize self.creation_time = creation_time self.modification_time = modification_time + self.created_by = created_by + self.updated_by = updated_by self.note = note def to_data(self): @@ -50,6 +56,8 @@ class WorkfileInfo: "filesize": self.filesize, "creation_time": self.creation_time, "modification_time": self.modification_time, + "created_by": self.created_by, + "updated_by": self.updated_by, "note": self.note, } @@ -212,6 +220,7 @@ class FileItem: dirpath (str): Directory path of file. filename (str): Filename. modified (float): Modified timestamp. + created_by (Optional[str]): Username. representation_id (Optional[str]): Representation id of published workfile. filepath (Optional[str]): Prepared filepath. @@ -223,6 +232,8 @@ class FileItem: dirpath, filename, modified, + created_by=None, + updated_by=None, representation_id=None, filepath=None, exists=None @@ -230,6 +241,8 @@ class FileItem: self.filename = filename self.dirpath = dirpath self.modified = modified + self.created_by = created_by + self.updated_by = updated_by self.representation_id = representation_id self._filepath = filepath self._exists = exists @@ -269,6 +282,7 @@ class FileItem: "filename": self.filename, "dirpath": self.dirpath, "modified": self.modified, + "created_by": self.created_by, "representation_id": self.representation_id, "filepath": self.filepath, "exists": self.exists, @@ -522,6 +536,16 @@ class AbstractWorkfilesFrontend(AbstractWorkfilesCommon): pass + @abstractmethod + def get_user_items_by_name(self): + """Get user items available on AYON server. + + Returns: + Dict[str, UserItem]: User items by username. + + """ + pass + # Host information @abstractmethod def get_workfile_extensions(self): diff --git a/client/ayon_core/tools/workfiles/control.py b/client/ayon_core/tools/workfiles/control.py index 3048e6be94..8fa9135bc0 100644 --- a/client/ayon_core/tools/workfiles/control.py +++ b/client/ayon_core/tools/workfiles/control.py @@ -19,6 +19,7 @@ from ayon_core.tools.common_models import ( HierarchyModel, HierarchyExpectedSelection, ProjectsModel, + UsersModel, ) from .abstract import ( @@ -161,6 +162,7 @@ class BaseWorkfileController( self._save_is_enabled = True # Expected selected folder and task + self._users_model = self._create_users_model() self._expected_selection = self._create_expected_selection_obj() self._selection_model = self._create_selection_model() self._projects_model = self._create_projects_model() @@ -176,6 +178,12 @@ class BaseWorkfileController( def is_host_valid(self): return self._host_is_valid + def _create_users_model(self): + return UsersModel(self) + + def _create_workfiles_model(self): + return WorkfilesModel(self) + def _create_expected_selection_obj(self): return WorkfilesToolExpectedSelection(self) @@ -188,9 +196,6 @@ class BaseWorkfileController( def _create_hierarchy_model(self): return HierarchyModel(self) - def _create_workfiles_model(self): - return WorkfilesModel(self) - @property def event_system(self): """Inner event system for workfiles tool controller. @@ -272,6 +277,9 @@ class BaseWorkfileController( {"enabled": enabled} ) + def get_user_items_by_name(self): + return self._users_model.get_user_items_by_name() + # Host information def get_workfile_extensions(self): host = self._host diff --git a/client/ayon_core/tools/workfiles/models/workfiles.py b/client/ayon_core/tools/workfiles/models/workfiles.py index 5f59b99b22..c93bbb6637 100644 --- a/client/ayon_core/tools/workfiles/models/workfiles.py +++ b/client/ayon_core/tools/workfiles/models/workfiles.py @@ -6,6 +6,7 @@ import arrow import ayon_api from ayon_api.operations import OperationsSession +from ayon_core.lib import get_ayon_username from ayon_core.pipeline.template_data import ( get_template_data, get_task_template_data, @@ -23,6 +24,8 @@ from ayon_core.tools.workfiles.abstract import ( WorkfileInfo, ) +_NOT_SET = object() + class CommentMatcher(object): """Use anatomy and work file data to parse comments from filenames. @@ -188,10 +191,17 @@ class WorkareaModel: if ext not in self._extensions: continue - modified = os.path.getmtime(filepath) - items.append( - FileItem(workdir, filename, modified) + workfile_info = self._controller.get_workfile_info( + folder_id, task_id, filepath ) + modified = os.path.getmtime(filepath) + items.append(FileItem( + workdir, + filename, + modified, + workfile_info.created_by, + workfile_info.updated_by, + )) return items def _get_template_key(self, fill_data): @@ -439,6 +449,7 @@ class WorkfileEntitiesModel: self._controller = controller self._cache = {} self._items = {} + self._current_username = _NOT_SET def _get_workfile_info_identifier( self, folder_id, task_id, rootless_path @@ -459,8 +470,12 @@ class WorkfileEntitiesModel: self, folder_id, task_id, workfile_info, filepath ): note = "" + created_by = None + updated_by = None if workfile_info: note = workfile_info["attrib"].get("description") or "" + created_by = workfile_info.get("createdBy") + updated_by = workfile_info.get("updatedBy") filestat = os.stat(filepath) return WorkfileInfo( @@ -470,6 +485,8 @@ class WorkfileEntitiesModel: filesize=filestat.st_size, creation_time=filestat.st_ctime, modification_time=filestat.st_mtime, + created_by=created_by, + updated_by=updated_by, note=note ) @@ -481,7 +498,7 @@ class WorkfileEntitiesModel: for workfile_info in ayon_api.get_workfiles_info( self._controller.get_current_project_name(), task_ids=[task_id], - fields=["id", "path", "attrib"], + fields=["id", "path", "attrib", "createdBy", "updatedBy"], ): workfile_identifier = self._get_workfile_info_identifier( folder_id, task_id, workfile_info["path"] @@ -525,18 +542,32 @@ class WorkfileEntitiesModel: self._items.pop(identifier, None) return - if note is None: - return - old_note = workfile_info.get("attrib", {}).get("note") new_workfile_info = copy.deepcopy(workfile_info) - attrib = new_workfile_info.setdefault("attrib", {}) - attrib["description"] = note + update_data = {} + if note is not None and old_note != note: + update_data["attrib"] = {"description": note} + attrib = new_workfile_info.setdefault("attrib", {}) + attrib["description"] = note + + username = self._get_current_username() + # Automatically fix 'createdBy' and 'updatedBy' fields + # NOTE both fields were not automatically filled by server + # until 1.1.3 release. + if workfile_info.get("createdBy") is None: + update_data["createdBy"] = username + new_workfile_info["createdBy"] = username + + if workfile_info.get("updatedBy") != username: + update_data["updatedBy"] = username + new_workfile_info["updatedBy"] = username + + if not update_data: + return + self._cache[identifier] = new_workfile_info self._items.pop(identifier, None) - if old_note == note: - return project_name = self._controller.get_current_project_name() @@ -545,7 +576,7 @@ class WorkfileEntitiesModel: project_name, "workfile", workfile_info["id"], - {"attrib": {"description": note}}, + update_data, ) session.commit() @@ -554,13 +585,18 @@ class WorkfileEntitiesModel: project_name = self._controller.get_current_project_name() + username = self._get_current_username() workfile_info = { "path": rootless_path, "taskId": task_id, "attrib": { "extension": extension, "description": note - } + }, + # TODO remove 'createdBy' and 'updatedBy' fields when server is + # or above 1.1.3 . + "createdBy": username, + "updatedBy": username, } session = OperationsSession() @@ -568,6 +604,11 @@ class WorkfileEntitiesModel: session.commit() return workfile_info + def _get_current_username(self): + if self._current_username is _NOT_SET: + self._current_username = get_ayon_username() + return self._current_username + class PublishWorkfilesModel: """Model for handling of published workfiles. @@ -599,7 +640,7 @@ class PublishWorkfilesModel: return self._cached_repre_extensions def _file_item_from_representation( - self, repre_entity, project_anatomy, task_name=None + self, repre_entity, project_anatomy, author, task_name=None ): if task_name is not None: task_info = repre_entity["context"].get("task") @@ -634,6 +675,8 @@ class PublishWorkfilesModel: dirpath, filename, created_at.float_timestamp, + author, + None, repre_entity["id"] ) @@ -643,9 +686,9 @@ class PublishWorkfilesModel: # Get subset docs of folder product_entities = ayon_api.get_products( project_name, - folder_ids=[folder_id], - product_types=["workfile"], - fields=["id", "name"] + folder_ids={folder_id}, + product_types={"workfile"}, + fields={"id", "name"} ) output = [] @@ -657,25 +700,33 @@ class PublishWorkfilesModel: version_entities = ayon_api.get_versions( project_name, product_ids=product_ids, - fields=["id", "productId"] + fields={"id", "author"} ) - version_ids = {version["id"] for version in version_entities} - if not version_ids: + versions_by_id = { + version["id"]: version + for version in version_entities + } + if not versions_by_id: return output # Query representations of filtered versions and add filter for # extension repre_entities = ayon_api.get_representations( project_name, - version_ids=version_ids + version_ids=set(versions_by_id) ) project_anatomy = self._controller.project_anatomy # Filter queried representations by task name if task is set file_items = [] for repre_entity in repre_entities: + version_id = repre_entity["versionId"] + version_entity = versions_by_id[version_id] file_item = self._file_item_from_representation( - repre_entity, project_anatomy, task_name + repre_entity, + project_anatomy, + version_entity["author"], + task_name, ) if file_item is not None: file_items.append(file_item) diff --git a/client/ayon_core/tools/workfiles/widgets/files_widget_published.py b/client/ayon_core/tools/workfiles/widgets/files_widget_published.py index bf36d790e9..2ce8569a9b 100644 --- a/client/ayon_core/tools/workfiles/widgets/files_widget_published.py +++ b/client/ayon_core/tools/workfiles/widgets/files_widget_published.py @@ -13,7 +13,8 @@ from .utils import BaseOverlayFrame REPRE_ID_ROLE = QtCore.Qt.UserRole + 1 FILEPATH_ROLE = QtCore.Qt.UserRole + 2 -DATE_MODIFIED_ROLE = QtCore.Qt.UserRole + 3 +AUTHOR_ROLE = QtCore.Qt.UserRole + 3 +DATE_MODIFIED_ROLE = QtCore.Qt.UserRole + 4 class PublishedFilesModel(QtGui.QStandardItemModel): @@ -23,13 +24,19 @@ class PublishedFilesModel(QtGui.QStandardItemModel): controller (AbstractWorkfilesFrontend): The control object. """ + columns = [ + "Name", + "Author", + "Date Modified", + ] + date_modified_col = columns.index("Date Modified") + def __init__(self, controller): super(PublishedFilesModel, self).__init__() - self.setColumnCount(2) - - self.setHeaderData(0, QtCore.Qt.Horizontal, "Name") - self.setHeaderData(1, QtCore.Qt.Horizontal, "Date Modified") + self.setColumnCount(len(self.columns)) + for idx, label in enumerate(self.columns): + self.setHeaderData(idx, QtCore.Qt.Horizontal, label) controller.register_event_callback( "selection.task.changed", @@ -185,6 +192,8 @@ class PublishedFilesModel(QtGui.QStandardItemModel): self._remove_empty_item() self._remove_missing_context_item() + user_items_by_name = self._controller.get_user_items_by_name() + items_to_remove = set(self._items_by_id.keys()) new_items = [] for file_item in file_items: @@ -205,8 +214,15 @@ class PublishedFilesModel(QtGui.QStandardItemModel): else: flags = QtCore.Qt.NoItemFlags + author = file_item.created_by + user_item = user_items_by_name.get(author) + if user_item is not None and user_item.full_name: + author = user_item.full_name + item.setFlags(flags) + item.setData(file_item.filepath, FILEPATH_ROLE) + item.setData(author, AUTHOR_ROLE) item.setData(file_item.modified, DATE_MODIFIED_ROLE) self._items_by_id[repre_id] = item @@ -225,22 +241,30 @@ class PublishedFilesModel(QtGui.QStandardItemModel): # Use flags of first column for all columns if index.column() != 0: index = self.index(index.row(), 0, index.parent()) - return super(PublishedFilesModel, self).flags(index) + return super().flags(index) def data(self, index, role=None): if role is None: role = QtCore.Qt.DisplayRole # Handle roles for first column - if index.column() == 1: - if role == QtCore.Qt.DecorationRole: - return None + col = index.column() + if col != 1: + return super().data(index, role) - if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole): + if role == QtCore.Qt.DecorationRole: + return None + + if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole): + if col == 1: + role = AUTHOR_ROLE + elif col == 2: role = DATE_MODIFIED_ROLE - index = self.index(index.row(), 0, index.parent()) + else: + return None + index = self.index(index.row(), 0, index.parent()) - return super(PublishedFilesModel, self).data(index, role) + return super().data(index, role) class SelectContextOverlay(BaseOverlayFrame): @@ -295,7 +319,7 @@ class PublishedFilesWidget(QtWidgets.QWidget): view.setModel(proxy_model) time_delegate = PrettyTimeDelegate() - view.setItemDelegateForColumn(1, time_delegate) + view.setItemDelegateForColumn(model.date_modified_col, time_delegate) # Default to a wider first filename column it is what we mostly care # about and the date modified is relatively small anyway. diff --git a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py index fe6abee951..5c102dcdd4 100644 --- a/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py +++ b/client/ayon_core/tools/workfiles/widgets/files_widget_workarea.py @@ -10,7 +10,8 @@ from ayon_core.tools.utils.delegates import PrettyTimeDelegate FILENAME_ROLE = QtCore.Qt.UserRole + 1 FILEPATH_ROLE = QtCore.Qt.UserRole + 2 -DATE_MODIFIED_ROLE = QtCore.Qt.UserRole + 3 +AUTHOR_ROLE = QtCore.Qt.UserRole + 3 +DATE_MODIFIED_ROLE = QtCore.Qt.UserRole + 4 class WorkAreaFilesModel(QtGui.QStandardItemModel): @@ -21,14 +22,20 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): """ refreshed = QtCore.Signal() + columns = [ + "Name", + "Author", + "Date Modified", + ] + date_modified_col = columns.index("Date Modified") def __init__(self, controller): super(WorkAreaFilesModel, self).__init__() - self.setColumnCount(2) + self.setColumnCount(len(self.columns)) - self.setHeaderData(0, QtCore.Qt.Horizontal, "Name") - self.setHeaderData(1, QtCore.Qt.Horizontal, "Date Modified") + for idx, label in enumerate(self.columns): + self.setHeaderData(idx, QtCore.Qt.Horizontal, label) controller.register_event_callback( "selection.folder.changed", @@ -186,6 +193,7 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): return self._remove_empty_item() self._remove_missing_context_item() + user_items_by_name = self._controller.get_user_items_by_name() items_to_remove = set(self._items_by_filename.keys()) new_items = [] @@ -205,7 +213,13 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): item.setData(file_item.filename, QtCore.Qt.DisplayRole) item.setData(file_item.filename, FILENAME_ROLE) + updated_by = file_item.updated_by + user_item = user_items_by_name.get(updated_by) + if user_item is not None and user_item.full_name: + updated_by = user_item.full_name + item.setData(file_item.filepath, FILEPATH_ROLE) + item.setData(updated_by, AUTHOR_ROLE) item.setData(file_item.modified, DATE_MODIFIED_ROLE) self._items_by_filename[file_item.filename] = item @@ -224,22 +238,30 @@ class WorkAreaFilesModel(QtGui.QStandardItemModel): # Use flags of first column for all columns if index.column() != 0: index = self.index(index.row(), 0, index.parent()) - return super(WorkAreaFilesModel, self).flags(index) + return super().flags(index) def data(self, index, role=None): if role is None: role = QtCore.Qt.DisplayRole # Handle roles for first column - if index.column() == 1: - if role == QtCore.Qt.DecorationRole: - return None + col = index.column() + if col == 0: + return super().data(index, role) - if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole): + if role == QtCore.Qt.DecorationRole: + return None + + if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole): + if col == 1: + role = AUTHOR_ROLE + elif col == 2: role = DATE_MODIFIED_ROLE - index = self.index(index.row(), 0, index.parent()) + else: + return None + index = self.index(index.row(), 0, index.parent()) - return super(WorkAreaFilesModel, self).data(index, role) + return super().data(index, role) def set_published_mode(self, published_mode): if self._published_mode == published_mode: @@ -279,7 +301,7 @@ class WorkAreaFilesWidget(QtWidgets.QWidget): view.setModel(proxy_model) time_delegate = PrettyTimeDelegate() - view.setItemDelegateForColumn(1, time_delegate) + view.setItemDelegateForColumn(model.date_modified_col, time_delegate) # Default to a wider first filename column it is what we mostly care # about and the date modified is relatively small anyway. diff --git a/client/ayon_core/tools/workfiles/widgets/side_panel.py b/client/ayon_core/tools/workfiles/widgets/side_panel.py index 5085f4701e..53fdf0e0ac 100644 --- a/client/ayon_core/tools/workfiles/widgets/side_panel.py +++ b/client/ayon_core/tools/workfiles/widgets/side_panel.py @@ -147,13 +147,38 @@ class SidePanelWidget(QtWidgets.QWidget): workfile_info.creation_time) modification_time = datetime.datetime.fromtimestamp( workfile_info.modification_time) + + user_items_by_name = self._controller.get_user_items_by_name() + + def convert_username(username): + user_item = user_items_by_name.get(username) + if user_item is not None and user_item.full_name: + return user_item.full_name + return username + + created_lines = [ + creation_time.strftime(datetime_format) + ] + if workfile_info.created_by: + created_lines.insert( + 0, convert_username(workfile_info.created_by) + ) + + modified_lines = [ + modification_time.strftime(datetime_format) + ] + if workfile_info.updated_by: + modified_lines.insert( + 0, convert_username(workfile_info.updated_by) + ) + lines = ( "Size:", size_value, "Created:", - creation_time.strftime(datetime_format), + "
".join(created_lines), "Modified:", - modification_time.strftime(datetime_format) + "
".join(modified_lines), ) self._orig_note = note self._note_input.setPlainText(note) diff --git a/client/ayon_core/tools/workfiles/widgets/window.py b/client/ayon_core/tools/workfiles/widgets/window.py index 1cfae7ec90..8bcff66f50 100644 --- a/client/ayon_core/tools/workfiles/widgets/window.py +++ b/client/ayon_core/tools/workfiles/widgets/window.py @@ -107,7 +107,7 @@ class WorkfilesToolWindow(QtWidgets.QWidget): split_widget.addWidget(tasks_widget) split_widget.addWidget(col_3_widget) split_widget.addWidget(side_panel) - split_widget.setSizes([255, 160, 455, 175]) + split_widget.setSizes([255, 175, 550, 190]) body_layout.addWidget(split_widget) @@ -169,7 +169,7 @@ class WorkfilesToolWindow(QtWidgets.QWidget): # Force focus on the open button by default, required for Houdini. self._files_widget.setFocus() - self.resize(1200, 600) + self.resize(1260, 600) def _create_col_1_widget(self, controller, parent): col_widget = QtWidgets.QWidget(parent) diff --git a/server/__init__.py b/server/__init__.py index 79f505ccd5..d60f50f471 100644 --- a/server/__init__.py +++ b/server/__init__.py @@ -2,7 +2,11 @@ from typing import Any from ayon_server.addons import BaseServerAddon -from .settings import CoreSettings, DEFAULT_VALUES +from .settings import ( + CoreSettings, + DEFAULT_VALUES, + convert_settings_overrides, +) class CoreAddon(BaseServerAddon): @@ -17,47 +21,8 @@ class CoreAddon(BaseServerAddon): source_version: str, overrides: dict[str, Any], ) -> dict[str, Any]: - self._convert_imagio_configs_0_3_1(overrides) + convert_settings_overrides(source_version, overrides) # Use super conversion return await super().convert_settings_overrides( source_version, overrides ) - - def _convert_imagio_configs_0_3_1(self, overrides): - """Imageio config settings did change to profiles since 0.3.1. .""" - imageio_overrides = overrides.get("imageio") or {} - if ( - "ocio_config" not in imageio_overrides - or "filepath" not in imageio_overrides["ocio_config"] - ): - return - - ocio_config = imageio_overrides.pop("ocio_config") - - filepath = ocio_config["filepath"] - if not filepath: - return - first_filepath = filepath[0] - ocio_config_profiles = imageio_overrides.setdefault( - "ocio_config_profiles", [] - ) - base_value = { - "type": "builtin_path", - "product_name": "", - "host_names": [], - "task_names": [], - "task_types": [], - "custom_path": "", - "builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio" - } - if first_filepath in ( - "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio", - "{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio", - ): - base_value["type"] = "builtin_path" - base_value["builtin_path"] = first_filepath - else: - base_value["type"] = "custom_path" - base_value["custom_path"] = first_filepath - - ocio_config_profiles.append(base_value) diff --git a/server/settings/__init__.py b/server/settings/__init__.py index 527a2bdc0c..4bb21a9644 100644 --- a/server/settings/__init__.py +++ b/server/settings/__init__.py @@ -1,7 +1,10 @@ from .main import CoreSettings, DEFAULT_VALUES +from .conversion import convert_settings_overrides __all__ = ( "CoreSettings", "DEFAULT_VALUES", + + "convert_settings_overrides", ) diff --git a/server/settings/conversion.py b/server/settings/conversion.py new file mode 100644 index 0000000000..f513738603 --- /dev/null +++ b/server/settings/conversion.py @@ -0,0 +1,86 @@ +import copy +from typing import Any + +from .publish_plugins import DEFAULT_PUBLISH_VALUES + + +def _convert_imageio_configs_0_3_1(overrides): + """Imageio config settings did change to profiles since 0.3.1. .""" + imageio_overrides = overrides.get("imageio") or {} + if ( + "ocio_config" not in imageio_overrides + or "filepath" not in imageio_overrides["ocio_config"] + ): + return + + ocio_config = imageio_overrides.pop("ocio_config") + + filepath = ocio_config["filepath"] + if not filepath: + return + first_filepath = filepath[0] + ocio_config_profiles = imageio_overrides.setdefault( + "ocio_config_profiles", [] + ) + base_value = { + "type": "builtin_path", + "product_name": "", + "host_names": [], + "task_names": [], + "task_types": [], + "custom_path": "", + "builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio" + } + if first_filepath in ( + "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio", + "{BUILTIN_OCIO_ROOT}/nuke-default/config.ocio", + ): + base_value["type"] = "builtin_path" + base_value["builtin_path"] = first_filepath + else: + base_value["type"] = "custom_path" + base_value["custom_path"] = first_filepath + + ocio_config_profiles.append(base_value) + + +def _convert_validate_version_0_3_3(publish_overrides): + """ValidateVersion plugin changed in 0.3.3.""" + if "ValidateVersion" not in publish_overrides: + return + + validate_version = publish_overrides["ValidateVersion"] + # Already new settings + if "plugin_state_profiles" in validate_version: + return + + # Use new default profile as base + profile = copy.deepcopy( + DEFAULT_PUBLISH_VALUES["ValidateVersion"]["plugin_state_profiles"][0] + ) + # Copy values from old overrides to new overrides + for key in { + "enabled", + "optional", + "active", + }: + if key not in validate_version: + continue + profile[key] = validate_version.pop(key) + + validate_version["plugin_state_profiles"] = [profile] + + +def _conver_publish_plugins(overrides): + if "publish" not in overrides: + return + _convert_validate_version_0_3_3(overrides["publish"]) + + +def convert_settings_overrides( + source_version: str, + overrides: dict[str, Any], +) -> dict[str, Any]: + _convert_imageio_configs_0_3_1(overrides) + _conver_publish_plugins(overrides) + return overrides diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 61e73ce912..2640a3db37 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -59,7 +59,7 @@ class CollectFramesFixDefModel(BaseSettingsModel): ) -class ValidateOutdatedContainersProfile(BaseSettingsModel): +class PluginStateByHostModelProfile(BaseSettingsModel): _layout = "expanded" # Filtering host_names: list[str] = SettingsField( @@ -72,17 +72,12 @@ class ValidateOutdatedContainersProfile(BaseSettingsModel): active: bool = SettingsField(True, title="Active") -class ValidateOutdatedContainersModel(BaseSettingsModel): - """Validate if Publishing intent was selected. - - It is possible to disable validation for specific publishing context - with profiles. - """ - +class PluginStateByHostModel(BaseSettingsModel): _isGroup = True - plugin_state_profiles: list[ValidateOutdatedContainersProfile] = SettingsField( + plugin_state_profiles: list[PluginStateByHostModelProfile] = SettingsField( default_factory=list, title="Plugin enable state profiles", + description="Change plugin state based on host name." ) @@ -563,7 +558,7 @@ class ExtractBurninProfile(BaseSettingsModel): _layout = "expanded" product_types: list[str] = SettingsField( default_factory=list, - title="Produt types" + title="Product types" ) hosts: list[str] = SettingsField( default_factory=list, @@ -793,12 +788,16 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=ValidateBaseModel, title="Validate Editorial Asset Name" ) - ValidateVersion: ValidateBaseModel = SettingsField( - default_factory=ValidateBaseModel, - title="Validate Version" + ValidateVersion: PluginStateByHostModel = SettingsField( + default_factory=PluginStateByHostModel, + title="Validate Version", + description=( + "Validate that product version to integrate" + " is newer than latest version in AYON." + ) ) - ValidateOutdatedContainers: ValidateOutdatedContainersModel = SettingsField( - default_factory=ValidateOutdatedContainersModel, + ValidateOutdatedContainers: PluginStateByHostModel = SettingsField( + default_factory=PluginStateByHostModel, title="Validate Containers" ) ValidateIntent: ValidateIntentModel = SettingsField( @@ -882,9 +881,21 @@ DEFAULT_PUBLISH_VALUES = { "active": True }, "ValidateVersion": { - "enabled": True, - "optional": False, - "active": True + "plugin_state_profiles": [ + { + "host_names": [ + "aftereffects", + "blender", + "houdini", + "maya", + "nuke", + "photoshop", + ], + "enabled": True, + "optional": False, + "active": True + } + ] }, "ValidateOutdatedContainers": { "plugin_state_profiles": [ diff --git a/client/ayon_core/hosts/max/__init__.py b/server_addon/max/client/ayon_max/__init__.py similarity index 100% rename from client/ayon_core/hosts/max/__init__.py rename to server_addon/max/client/ayon_max/__init__.py diff --git a/client/ayon_core/hosts/max/addon.py b/server_addon/max/client/ayon_max/addon.py similarity index 100% rename from client/ayon_core/hosts/max/addon.py rename to server_addon/max/client/ayon_max/addon.py diff --git a/client/ayon_core/hosts/max/api/__init__.py b/server_addon/max/client/ayon_max/api/__init__.py similarity index 100% rename from client/ayon_core/hosts/max/api/__init__.py rename to server_addon/max/client/ayon_max/api/__init__.py diff --git a/client/ayon_core/hosts/max/api/action.py b/server_addon/max/client/ayon_max/api/action.py similarity index 100% rename from client/ayon_core/hosts/max/api/action.py rename to server_addon/max/client/ayon_max/api/action.py diff --git a/client/ayon_core/hosts/max/api/colorspace.py b/server_addon/max/client/ayon_max/api/colorspace.py similarity index 100% rename from client/ayon_core/hosts/max/api/colorspace.py rename to server_addon/max/client/ayon_max/api/colorspace.py diff --git a/client/ayon_core/hosts/max/api/lib.py b/server_addon/max/client/ayon_max/api/lib.py similarity index 99% rename from client/ayon_core/hosts/max/api/lib.py rename to server_addon/max/client/ayon_max/api/lib.py index f20f754248..eb22dbafd2 100644 --- a/client/ayon_core/hosts/max/api/lib.py +++ b/server_addon/max/client/ayon_max/api/lib.py @@ -20,7 +20,7 @@ from pymxs import runtime as rt JSON_PREFIX = "JSON::" -log = logging.getLogger("ayon_core.hosts.max") +log = logging.getLogger("ayon_max") def get_main_window(): diff --git a/client/ayon_core/hosts/max/api/lib_renderproducts.py b/server_addon/max/client/ayon_max/api/lib_renderproducts.py similarity index 99% rename from client/ayon_core/hosts/max/api/lib_renderproducts.py rename to server_addon/max/client/ayon_max/api/lib_renderproducts.py index 710ed0031a..82a6a0c20c 100644 --- a/client/ayon_core/hosts/max/api/lib_renderproducts.py +++ b/server_addon/max/client/ayon_max/api/lib_renderproducts.py @@ -6,7 +6,7 @@ import os from pymxs import runtime as rt -from ayon_core.hosts.max.api.lib import get_current_renderer +from ayon_max.api.lib import get_current_renderer from ayon_core.pipeline import get_current_project_name from ayon_core.settings import get_project_settings diff --git a/client/ayon_core/hosts/max/api/lib_rendersettings.py b/server_addon/max/client/ayon_max/api/lib_rendersettings.py similarity index 99% rename from client/ayon_core/hosts/max/api/lib_rendersettings.py rename to server_addon/max/client/ayon_max/api/lib_rendersettings.py index 35b6d064c1..4b65e1397e 100644 --- a/client/ayon_core/hosts/max/api/lib_rendersettings.py +++ b/server_addon/max/client/ayon_max/api/lib_rendersettings.py @@ -5,7 +5,7 @@ from ayon_core.settings import get_project_settings from ayon_core.pipeline import get_current_project_name from ayon_core.pipeline.context_tools import get_current_folder_entity -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api.lib import ( set_render_frame_range, get_current_renderer, get_default_render_folder diff --git a/client/ayon_core/hosts/max/api/menu.py b/server_addon/max/client/ayon_max/api/menu.py similarity index 99% rename from client/ayon_core/hosts/max/api/menu.py rename to server_addon/max/client/ayon_max/api/menu.py index c6ceeb3a43..25dd39fd84 100644 --- a/client/ayon_core/hosts/max/api/menu.py +++ b/server_addon/max/client/ayon_max/api/menu.py @@ -5,7 +5,7 @@ from qtpy import QtWidgets, QtCore from pymxs import runtime as rt from ayon_core.tools.utils import host_tools -from ayon_core.hosts.max.api import lib +from ayon_max.api import lib class AYONMenu(object): diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/server_addon/max/client/ayon_max/api/pipeline.py similarity index 97% rename from client/ayon_core/hosts/max/api/pipeline.py rename to server_addon/max/client/ayon_max/api/pipeline.py index d9cfc3407f..5f5e896e86 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/server_addon/max/client/ayon_max/api/pipeline.py @@ -14,14 +14,14 @@ from ayon_core.pipeline import ( AVALON_CONTAINER_ID, AYON_CONTAINER_ID, ) -from ayon_core.hosts.max.api.menu import AYONMenu -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.plugin import MS_CUSTOM_ATTRIB -from ayon_core.hosts.max import MAX_HOST_DIR +from ayon_max.api.menu import AYONMenu +from ayon_max.api import lib +from ayon_max.api.plugin import MS_CUSTOM_ATTRIB +from ayon_max import MAX_HOST_DIR from pymxs import runtime as rt # noqa -log = logging.getLogger("ayon_core.hosts.max") +log = logging.getLogger("ayon_max") PLUGINS_DIR = os.path.join(MAX_HOST_DIR, "plugins") PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") diff --git a/client/ayon_core/hosts/max/api/plugin.py b/server_addon/max/client/ayon_max/api/plugin.py similarity index 100% rename from client/ayon_core/hosts/max/api/plugin.py rename to server_addon/max/client/ayon_max/api/plugin.py diff --git a/client/ayon_core/hosts/max/api/preview_animation.py b/server_addon/max/client/ayon_max/api/preview_animation.py similarity index 99% rename from client/ayon_core/hosts/max/api/preview_animation.py rename to server_addon/max/client/ayon_max/api/preview_animation.py index 399d3b6222..acda5360a1 100644 --- a/client/ayon_core/hosts/max/api/preview_animation.py +++ b/server_addon/max/client/ayon_max/api/preview_animation.py @@ -3,7 +3,7 @@ import contextlib from pymxs import runtime as rt from .lib import get_max_version, render_resolution -log = logging.getLogger("ayon_core.hosts.max") +log = logging.getLogger("ayon_max") @contextlib.contextmanager diff --git a/client/ayon_core/hosts/max/hooks/force_startup_script.py b/server_addon/max/client/ayon_max/hooks/force_startup_script.py similarity index 94% rename from client/ayon_core/hosts/max/hooks/force_startup_script.py rename to server_addon/max/client/ayon_max/hooks/force_startup_script.py index 417f0049ab..1699ea300a 100644 --- a/client/ayon_core/hosts/max/hooks/force_startup_script.py +++ b/server_addon/max/client/ayon_max/hooks/force_startup_script.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Pre-launch to force 3ds max startup script.""" import os -from ayon_core.hosts.max import MAX_HOST_DIR +from ayon_max import MAX_HOST_DIR from ayon_applications import PreLaunchHook, LaunchTypes diff --git a/client/ayon_core/hosts/max/hooks/inject_python.py b/server_addon/max/client/ayon_max/hooks/inject_python.py similarity index 100% rename from client/ayon_core/hosts/max/hooks/inject_python.py rename to server_addon/max/client/ayon_max/hooks/inject_python.py diff --git a/client/ayon_core/hosts/max/hooks/set_paths.py b/server_addon/max/client/ayon_max/hooks/set_paths.py similarity index 100% rename from client/ayon_core/hosts/max/hooks/set_paths.py rename to server_addon/max/client/ayon_max/hooks/set_paths.py diff --git a/client/ayon_core/hosts/max/plugins/__init__.py b/server_addon/max/client/ayon_max/plugins/__init__.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/__init__.py rename to server_addon/max/client/ayon_max/plugins/__init__.py diff --git a/client/ayon_core/hosts/max/plugins/create/create_camera.py b/server_addon/max/client/ayon_max/plugins/create/create_camera.py similarity index 80% rename from client/ayon_core/hosts/max/plugins/create/create_camera.py rename to server_addon/max/client/ayon_max/plugins/create/create_camera.py index 42f8cb716d..451e178afc 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_camera.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_camera.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreateCamera(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreateCamera(plugin.MaxCreator): label = "Camera" product_type = "camera" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_maxScene.py b/server_addon/max/client/ayon_max/plugins/create/create_maxScene.py similarity index 81% rename from client/ayon_core/hosts/max/plugins/create/create_maxScene.py rename to server_addon/max/client/ayon_max/plugins/create/create_maxScene.py index 0e5768b267..ee58ef663d 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_maxScene.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_maxScene.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating raw max scene.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreateMaxScene(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreateMaxScene(plugin.MaxCreator): label = "Max Scene" product_type = "maxScene" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_model.py b/server_addon/max/client/ayon_max/plugins/create/create_model.py similarity index 79% rename from client/ayon_core/hosts/max/plugins/create/create_model.py rename to server_addon/max/client/ayon_max/plugins/create/create_model.py index 297c92067e..f48182ecd7 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_model.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_model.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for model.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreateModel(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreateModel(plugin.MaxCreator): label = "Model" product_type = "model" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_pointcache.py b/server_addon/max/client/ayon_max/plugins/create/create_pointcache.py similarity index 82% rename from client/ayon_core/hosts/max/plugins/create/create_pointcache.py rename to server_addon/max/client/ayon_max/plugins/create/create_pointcache.py index eb0686a0c0..6d7aabe12c 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_pointcache.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_pointcache.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating pointcache alembics.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreatePointCache(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreatePointCache(plugin.MaxCreator): label = "Point Cache" product_type = "pointcache" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_pointcloud.py b/server_addon/max/client/ayon_max/plugins/create/create_pointcloud.py similarity index 82% rename from client/ayon_core/hosts/max/plugins/create/create_pointcloud.py rename to server_addon/max/client/ayon_max/plugins/create/create_pointcloud.py index 9a58f4e624..52014d77b2 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_pointcloud.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_pointcloud.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating point cloud.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreatePointCloud(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreatePointCloud(plugin.MaxCreator): label = "Point Cloud" product_type = "pointcloud" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_redshift_proxy.py b/server_addon/max/client/ayon_max/plugins/create/create_redshift_proxy.py similarity index 80% rename from client/ayon_core/hosts/max/plugins/create/create_redshift_proxy.py rename to server_addon/max/client/ayon_max/plugins/create/create_redshift_proxy.py index 17f5349dc1..bcc96c7efe 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_redshift_proxy.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_redshift_proxy.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreateRedshiftProxy(plugin.MaxCreator): @@ -8,3 +8,5 @@ class CreateRedshiftProxy(plugin.MaxCreator): label = "Redshift Proxy" product_type = "redshiftproxy" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_render.py b/server_addon/max/client/ayon_max/plugins/create/create_render.py similarity index 93% rename from client/ayon_core/hosts/max/plugins/create/create_render.py rename to server_addon/max/client/ayon_max/plugins/create/create_render.py index 60fe628a5e..d1e236f3ef 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_render.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_render.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" import os -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin from ayon_core.lib import BoolDef -from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings +from ayon_max.api.lib_rendersettings import RenderSettings class CreateRender(plugin.MaxCreator): @@ -13,6 +13,8 @@ class CreateRender(plugin.MaxCreator): product_type = "maxrender" icon = "gear" + settings_category = "max" + def create(self, product_name, instance_data, pre_create_data): from pymxs import runtime as rt file = rt.maxFileName diff --git a/client/ayon_core/hosts/max/plugins/create/create_review.py b/server_addon/max/client/ayon_max/plugins/create/create_review.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/create/create_review.py rename to server_addon/max/client/ayon_max/plugins/create/create_review.py index 0a0ffd2e46..a49490519a 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_review.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_review.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating review in Max.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin from ayon_core.lib import BoolDef, EnumDef, NumberDef @@ -12,6 +12,8 @@ class CreateReview(plugin.MaxCreator): product_type = "review" icon = "video-camera" + settings_category = "max" + review_width = 1920 review_height = 1080 percentSize = 100 diff --git a/client/ayon_core/hosts/max/plugins/create/create_tycache.py b/server_addon/max/client/ayon_max/plugins/create/create_tycache.py similarity index 80% rename from client/ayon_core/hosts/max/plugins/create/create_tycache.py rename to server_addon/max/client/ayon_max/plugins/create/create_tycache.py index 2b3893bf13..cbdd94e272 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_tycache.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_tycache.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating TyCache.""" -from ayon_core.hosts.max.api import plugin +from ayon_max.api import plugin class CreateTyCache(plugin.MaxCreator): @@ -9,3 +9,5 @@ class CreateTyCache(plugin.MaxCreator): label = "TyCache" product_type = "tycache" icon = "gear" + + settings_category = "max" diff --git a/client/ayon_core/hosts/max/plugins/create/create_workfile.py b/server_addon/max/client/ayon_max/plugins/create/create_workfile.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/create/create_workfile.py rename to server_addon/max/client/ayon_max/plugins/create/create_workfile.py index 901da6254c..35c41f0fcc 100644 --- a/client/ayon_core/hosts/max/plugins/create/create_workfile.py +++ b/server_addon/max/client/ayon_max/plugins/create/create_workfile.py @@ -3,8 +3,8 @@ import ayon_api from ayon_core.pipeline import CreatedInstance, AutoCreator -from ayon_core.hosts.max.api import plugin -from ayon_core.hosts.max.api.lib import read, imprint +from ayon_max.api import plugin +from ayon_max.api.lib import read, imprint from pymxs import runtime as rt @@ -17,6 +17,8 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator): default_variant = "Main" + settings_category = "max" + def create(self): variant = self.default_variant current_instance = next( diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/server_addon/max/client/ayon_max/plugins/load/load_camera_fbx.py similarity index 96% rename from client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py rename to server_addon/max/client/ayon_max/plugins/load/load_camera_fbx.py index 6f1e9988c5..81ea15d52a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_camera_fbx.py @@ -1,12 +1,12 @@ import os -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_namespace, object_transform_set ) -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/server_addon/max/client/ayon_max/plugins/load/load_max_scene.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/load/load_max_scene.py rename to server_addon/max/client/ayon_max/plugins/load/load_max_scene.py index 97b8c6cd52..7fca69b193 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_max_scene.py @@ -1,14 +1,14 @@ import os from qtpy import QtWidgets, QtCore from ayon_core.lib.attribute_definitions import EnumDef -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_namespace, object_transform_set, is_headless ) -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, remove_container_data diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/server_addon/max/client/ayon_max/plugins/load/load_model.py similarity index 96% rename from client/ayon_core/hosts/max/plugins/load/load_model.py rename to server_addon/max/client/ayon_max/plugins/load/load_model.py index 1070fce2bd..2a6bc45c18 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_model.py @@ -1,12 +1,12 @@ import os from ayon_core.pipeline import load, get_representation_path -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, remove_container_data ) -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( maintained_selection, unique_namespace ) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/server_addon/max/client/ayon_max/plugins/load/load_model_fbx.py similarity index 94% rename from client/ayon_core/hosts/max/plugins/load/load_model_fbx.py rename to server_addon/max/client/ayon_max/plugins/load/load_model_fbx.py index 6f5de20ae0..2775e1b453 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_model_fbx.py @@ -1,17 +1,17 @@ import os from ayon_core.pipeline import load, get_representation_path -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, remove_container_data ) -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_namespace, object_transform_set ) -from ayon_core.hosts.max.api.lib import maintained_selection +from ayon_max.api.lib import maintained_selection class FbxModelLoader(load.LoaderPlugin): diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/server_addon/max/client/ayon_max/plugins/load/load_model_obj.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/load/load_model_obj.py rename to server_addon/max/client/ayon_max/plugins/load/load_model_obj.py index a9119259df..d38aadb5bc 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_model_obj.py @@ -1,13 +1,13 @@ import os -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_namespace, maintained_selection, object_transform_set ) -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/server_addon/max/client/ayon_max/plugins/load/load_model_usd.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/load/load_model_usd.py rename to server_addon/max/client/ayon_max/plugins/load/load_model_usd.py index 2ed5d64a18..f4dd41d5db 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_model_usd.py @@ -2,15 +2,15 @@ import os from pymxs import runtime as rt from ayon_core.pipeline.load import LoadError -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_namespace, object_transform_set, get_plugins ) -from ayon_core.hosts.max.api.lib import maintained_selection -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.lib import maintained_selection +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/server_addon/max/client/ayon_max/plugins/load/load_pointcache.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/load/load_pointcache.py rename to server_addon/max/client/ayon_max/plugins/load/load_pointcache.py index 0743b3bb34..d7def3d0ba 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_pointcache.py @@ -6,9 +6,9 @@ Because of limited api, alembics can be only loaded, but not easily updated. """ import os from ayon_core.pipeline import load, get_representation_path -from ayon_core.hosts.max.api import lib, maintained_selection -from ayon_core.hosts.max.api.lib import unique_namespace -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api import lib, maintained_selection +from ayon_max.api.lib import unique_namespace +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, remove_container_data diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/server_addon/max/client/ayon_max/plugins/load/load_pointcache_ornatrix.py similarity index 96% rename from client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py rename to server_addon/max/client/ayon_max/plugins/load/load_pointcache_ornatrix.py index 47690f84e9..bc997951c1 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_pointcache_ornatrix.py @@ -1,20 +1,20 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.pipeline.load import LoadError -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, remove_container_data ) -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api.lib import ( unique_namespace, get_namespace, object_transform_set, get_plugins ) -from ayon_core.hosts.max.api import lib +from ayon_max.api import lib from pymxs import runtime as rt diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/server_addon/max/client/ayon_max/plugins/load/load_pointcloud.py similarity index 92% rename from client/ayon_core/hosts/max/plugins/load/load_pointcloud.py rename to server_addon/max/client/ayon_max/plugins/load/load_pointcloud.py index 0e79882fc5..0fb506d5bd 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_pointcloud.py @@ -1,11 +1,11 @@ import os -from ayon_core.hosts.max.api import lib, maintained_selection -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib, maintained_selection +from ayon_max.api.lib import ( unique_namespace, ) -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/server_addon/max/client/ayon_max/plugins/load/load_redshift_proxy.py similarity index 94% rename from client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py rename to server_addon/max/client/ayon_max/plugins/load/load_redshift_proxy.py index 22d42390d9..3fd84b7538 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_redshift_proxy.py @@ -6,14 +6,14 @@ from ayon_core.pipeline import ( get_representation_path ) from ayon_core.pipeline.load import LoadError -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, update_custom_attribute_data, get_previous_loaded_object, remove_container_data ) -from ayon_core.hosts.max.api import lib -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib +from ayon_max.api.lib import ( unique_namespace, get_plugins ) diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/server_addon/max/client/ayon_max/plugins/load/load_tycache.py similarity index 92% rename from client/ayon_core/hosts/max/plugins/load/load_tycache.py rename to server_addon/max/client/ayon_max/plugins/load/load_tycache.py index 7a5296d933..e087d5599a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/server_addon/max/client/ayon_max/plugins/load/load_tycache.py @@ -1,10 +1,10 @@ import os -from ayon_core.hosts.max.api import lib, maintained_selection -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api import lib, maintained_selection +from ayon_max.api.lib import ( unique_namespace, ) -from ayon_core.hosts.max.api.pipeline import ( +from ayon_max.api.pipeline import ( containerise, get_previous_loaded_object, update_custom_attribute_data, diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_current_file.py b/server_addon/max/client/ayon_max/plugins/publish/collect_current_file.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/collect_current_file.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_current_file.py diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_frame_range.py b/server_addon/max/client/ayon_max/plugins/publish/collect_frame_range.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/collect_frame_range.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_frame_range.py diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_members.py b/server_addon/max/client/ayon_max/plugins/publish/collect_members.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/collect_members.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_members.py diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_render.py b/server_addon/max/client/ayon_max/plugins/publish/collect_render.py similarity index 94% rename from client/ayon_core/hosts/max/plugins/publish/collect_render.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_render.py index 4ad9dfb3a3..a5e8d65df2 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_render.py +++ b/server_addon/max/client/ayon_max/plugins/publish/collect_render.py @@ -5,10 +5,10 @@ import pyblish.api from pymxs import runtime as rt from ayon_core.pipeline.publish import KnownPublishError -from ayon_core.hosts.max.api import colorspace -from ayon_core.hosts.max.api.lib import get_max_version, get_current_renderer -from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings -from ayon_core.hosts.max.api.lib_renderproducts import RenderProducts +from ayon_max.api import colorspace +from ayon_max.api.lib import get_max_version, get_current_renderer +from ayon_max.api.lib_rendersettings import RenderSettings +from ayon_max.api.lib_renderproducts import RenderProducts class CollectRender(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_review.py b/server_addon/max/client/ayon_max/plugins/publish/collect_review.py similarity index 99% rename from client/ayon_core/hosts/max/plugins/publish/collect_review.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_review.py index d746e2b2db..321aa7439c 100644 --- a/client/ayon_core/hosts/max/plugins/publish/collect_review.py +++ b/server_addon/max/client/ayon_max/plugins/publish/collect_review.py @@ -4,7 +4,7 @@ import pyblish.api from pymxs import runtime as rt from ayon_core.lib import BoolDef -from ayon_core.hosts.max.api.lib import get_max_version +from ayon_max.api.lib import get_max_version from ayon_core.pipeline.publish import ( AYONPyblishPluginMixin, KnownPublishError diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_tycache_attributes.py b/server_addon/max/client/ayon_max/plugins/publish/collect_tycache_attributes.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/collect_tycache_attributes.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_tycache_attributes.py diff --git a/client/ayon_core/hosts/max/plugins/publish/collect_workfile.py b/server_addon/max/client/ayon_max/plugins/publish/collect_workfile.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/collect_workfile.py rename to server_addon/max/client/ayon_max/plugins/publish/collect_workfile.py diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_alembic.py b/server_addon/max/client/ayon_max/plugins/publish/extract_alembic.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/extract_alembic.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_alembic.py index 67cec23ecc..b0999e5a78 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_alembic.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_alembic.py @@ -41,8 +41,8 @@ import os import pyblish.api from ayon_core.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection -from ayon_core.hosts.max.api.lib import suspended_refresh +from ayon_max.api import maintained_selection +from ayon_max.api.lib import suspended_refresh from ayon_core.lib import BoolDef diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_fbx.py b/server_addon/max/client/ayon_max/plugins/publish/extract_fbx.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/publish/extract_fbx.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_fbx.py index 3d80588c47..bdfc1d0d78 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_fbx.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_fbx.py @@ -2,8 +2,8 @@ import os import pyblish.api from ayon_core.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection -from ayon_core.hosts.max.api.lib import convert_unit_scale +from ayon_max.api import maintained_selection +from ayon_max.api.lib import convert_unit_scale class ExtractModelFbx(publish.Extractor, OptionalPyblishPluginMixin): diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_max_scene_raw.py b/server_addon/max/client/ayon_max/plugins/publish/extract_max_scene_raw.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/extract_max_scene_raw.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_max_scene_raw.py index f5c703564c..ecde6d2ce9 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_max_scene_raw.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_max_scene_raw.py @@ -15,6 +15,8 @@ class ExtractMaxSceneRaw(publish.Extractor, OptionalPyblishPluginMixin): families = ["camera", "maxScene", "model"] optional = True + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_model_obj.py b/server_addon/max/client/ayon_max/plugins/publish/extract_model_obj.py similarity index 93% rename from client/ayon_core/hosts/max/plugins/publish/extract_model_obj.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_model_obj.py index 03bdde7d5d..6556bd7809 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_model_obj.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_model_obj.py @@ -2,8 +2,8 @@ import os import pyblish.api from ayon_core.pipeline import publish, OptionalPyblishPluginMixin from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection -from ayon_core.hosts.max.api.lib import suspended_refresh +from ayon_max.api import maintained_selection +from ayon_max.api.lib import suspended_refresh from ayon_core.pipeline.publish import KnownPublishError @@ -18,6 +18,8 @@ class ExtractModelObj(publish.Extractor, OptionalPyblishPluginMixin): families = ["model"] optional = True + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_model_usd.py b/server_addon/max/client/ayon_max/plugins/publish/extract_model_usd.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/extract_model_usd.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_model_usd.py index 64791e4c7d..a48126c6e5 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_model_usd.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_model_usd.py @@ -3,7 +3,7 @@ import os import pyblish.api from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection +from ayon_max.api import maintained_selection from ayon_core.pipeline import OptionalPyblishPluginMixin, publish @@ -17,6 +17,8 @@ class ExtractModelUSD(publish.Extractor, families = ["model"] optional = True + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py b/server_addon/max/client/ayon_max/plugins/publish/extract_pointcloud.py similarity index 99% rename from client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_pointcloud.py index 67dde7f0a6..f763325eb9 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_pointcloud.py @@ -3,7 +3,7 @@ import os import pyblish.api from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection +from ayon_max.api import maintained_selection from ayon_core.pipeline import publish diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_redshift_proxy.py b/server_addon/max/client/ayon_max/plugins/publish/extract_redshift_proxy.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/extract_redshift_proxy.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_redshift_proxy.py index 6a647670bc..dfb3527be1 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_redshift_proxy.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_redshift_proxy.py @@ -2,7 +2,7 @@ import os import pyblish.api from ayon_core.pipeline import publish from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection +from ayon_max.api import maintained_selection class ExtractRedshiftProxy(publish.Extractor): diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_review_animation.py b/server_addon/max/client/ayon_max/plugins/publish/extract_review_animation.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/extract_review_animation.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_review_animation.py index 12f1fbb63b..b6397d404e 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_review_animation.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_review_animation.py @@ -1,7 +1,7 @@ import os import pyblish.api from ayon_core.pipeline import publish -from ayon_core.hosts.max.api.preview_animation import ( +from ayon_max.api.preview_animation import ( render_preview_animation ) diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_thumbnail.py b/server_addon/max/client/ayon_max/plugins/publish/extract_thumbnail.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/publish/extract_thumbnail.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_thumbnail.py index 5764ce98c4..183e381be2 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_thumbnail.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_thumbnail.py @@ -1,7 +1,7 @@ import os import pyblish.api from ayon_core.pipeline import publish -from ayon_core.hosts.max.api.preview_animation import render_preview_animation +from ayon_max.api.preview_animation import render_preview_animation class ExtractThumbnail(publish.Extractor): diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_tycache.py b/server_addon/max/client/ayon_max/plugins/publish/extract_tycache.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/publish/extract_tycache.py rename to server_addon/max/client/ayon_max/plugins/publish/extract_tycache.py index 50bb06a765..576abe32a2 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_tycache.py +++ b/server_addon/max/client/ayon_max/plugins/publish/extract_tycache.py @@ -3,7 +3,7 @@ import os import pyblish.api from pymxs import runtime as rt -from ayon_core.hosts.max.api import maintained_selection +from ayon_max.api import maintained_selection from ayon_core.pipeline import publish diff --git a/client/ayon_core/hosts/max/plugins/publish/help/validate_model_name.xml b/server_addon/max/client/ayon_max/plugins/publish/help/validate_model_name.xml similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/help/validate_model_name.xml rename to server_addon/max/client/ayon_max/plugins/publish/help/validate_model_name.xml diff --git a/client/ayon_core/hosts/max/plugins/publish/increment_workfile_version.py b/server_addon/max/client/ayon_max/plugins/publish/increment_workfile_version.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/increment_workfile_version.py rename to server_addon/max/client/ayon_max/plugins/publish/increment_workfile_version.py diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/server_addon/max/client/ayon_max/plugins/publish/save_scene.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/save_scene.py rename to server_addon/max/client/ayon_max/plugins/publish/save_scene.py diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scenes_for_cameras.py b/server_addon/max/client/ayon_max/plugins/publish/save_scenes_for_cameras.py similarity index 96% rename from client/ayon_core/hosts/max/plugins/publish/save_scenes_for_cameras.py rename to server_addon/max/client/ayon_max/plugins/publish/save_scenes_for_cameras.py index 817db1b28f..a211210550 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scenes_for_cameras.py +++ b/server_addon/max/client/ayon_max/plugins/publish/save_scenes_for_cameras.py @@ -5,8 +5,8 @@ import tempfile from pymxs import runtime as rt from ayon_core.lib import run_subprocess -from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings -from ayon_core.hosts.max.api.lib_renderproducts import RenderProducts +from ayon_max.api.lib_rendersettings import RenderSettings +from ayon_max.api.lib_renderproducts import RenderProducts class SaveScenesForCamera(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py b/server_addon/max/client/ayon_max/plugins/publish/validate_attributes.py similarity index 99% rename from client/ayon_core/hosts/max/plugins/publish/validate_attributes.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_attributes.py index 354539871f..a489533b2c 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_attributes.py @@ -61,6 +61,8 @@ class ValidateAttributes(OptionalPyblishPluginMixin, actions = [RepairContextAction] optional = True + settings_category = "max" + @classmethod def get_invalid(cls, context): attributes = json.loads( diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_camera_attributes.py b/server_addon/max/client/ayon_max/plugins/publish/validate_camera_attributes.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/validate_camera_attributes.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_camera_attributes.py index 9398cba2b7..63a2ef39a7 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_camera_attributes.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_camera_attributes.py @@ -6,7 +6,7 @@ from ayon_core.pipeline.publish import ( OptionalPyblishPluginMixin, PublishValidationError ) -from ayon_core.hosts.max.api.action import SelectInvalidAction +from ayon_max.api.action import SelectInvalidAction class ValidateCameraAttributes(OptionalPyblishPluginMixin, @@ -23,6 +23,8 @@ class ValidateCameraAttributes(OptionalPyblishPluginMixin, actions = [SelectInvalidAction, RepairAction] optional = True + settings_category = "max" + DEFAULTS = ["fov", "nearrange", "farrange", "nearclip", "farclip"] CAM_TYPE = ["Freecamera", "Targetcamera", diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_camera_contents.py b/server_addon/max/client/ayon_max/plugins/publish/validate_camera_contents.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_camera_contents.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_camera_contents.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_extended_viewport.py b/server_addon/max/client/ayon_max/plugins/publish/validate_extended_viewport.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_extended_viewport.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_extended_viewport.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_frame_range.py b/server_addon/max/client/ayon_max/plugins/publish/validate_frame_range.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/validate_frame_range.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_frame_range.py index 11b55232d5..9a9f22dd3e 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_frame_range.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_frame_range.py @@ -10,7 +10,7 @@ from ayon_core.pipeline.publish import ( PublishValidationError, KnownPublishError ) -from ayon_core.hosts.max.api.lib import get_frame_range, set_timeline +from ayon_max.api.lib import get_frame_range, set_timeline class ValidateFrameRange(pyblish.api.InstancePlugin, @@ -36,6 +36,8 @@ class ValidateFrameRange(pyblish.api.InstancePlugin, optional = True actions = [RepairAction] + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): self.log.debug("Skipping Validate Frame Range...") diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_instance_has_members.py b/server_addon/max/client/ayon_max/plugins/publish/validate_instance_has_members.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_instance_has_members.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_instance_has_members.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_instance_in_context.py b/server_addon/max/client/ayon_max/plugins/publish/validate_instance_in_context.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/validate_instance_in_context.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_instance_in_context.py index 5107665235..d5bdfe4eb0 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_instance_in_context.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_instance_in_context.py @@ -7,7 +7,7 @@ from ayon_core.pipeline.publish import ( PublishValidationError, OptionalPyblishPluginMixin ) -from ayon_core.hosts.max.api.action import SelectInvalidAction +from ayon_max.api.action import SelectInvalidAction from pymxs import runtime as rt @@ -27,6 +27,8 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin, hosts = ["max"] actions = [SelectInvalidAction, RepairAction] + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py b/server_addon/max/client/ayon_max/plugins/publish/validate_loaded_plugin.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_loaded_plugin.py index e278041b6b..1fddc7998d 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_loaded_plugin.py @@ -9,7 +9,7 @@ from ayon_core.pipeline.publish import ( OptionalPyblishPluginMixin, PublishValidationError ) -from ayon_core.hosts.max.api.lib import get_plugins +from ayon_max.api.lib import get_plugins class ValidateLoadedPlugin(OptionalPyblishPluginMixin, @@ -25,6 +25,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, optional = True actions = [RepairAction] + settings_category = "max" + family_plugins_mapping = [] @classmethod diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_mesh_has_uv.py b/server_addon/max/client/ayon_max/plugins/publish/validate_mesh_has_uv.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/publish/validate_mesh_has_uv.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_mesh_has_uv.py index ccd91da2be..31143a60c0 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_mesh_has_uv.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_mesh_has_uv.py @@ -1,6 +1,6 @@ import pyblish.api -from ayon_core.hosts.max.api.action import SelectInvalidAction +from ayon_max.api.action import SelectInvalidAction from ayon_core.pipeline.publish import ( ValidateMeshOrder, OptionalPyblishPluginMixin, @@ -30,6 +30,8 @@ class ValidateMeshHasUVs(pyblish.api.InstancePlugin, actions = [SelectInvalidAction] optional = True + settings_category = "max" + @classmethod def get_invalid(cls, instance): meshes = [member for member in instance.data["members"] diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_model_contents.py b/server_addon/max/client/ayon_max/plugins/publish/validate_model_contents.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_model_contents.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_model_contents.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py b/server_addon/max/client/ayon_max/plugins/publish/validate_model_name.py similarity index 97% rename from client/ayon_core/hosts/max/plugins/publish/validate_model_name.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_model_name.py index eb86e2e5bd..d691b739b7 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_model_name.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_model_name.py @@ -4,7 +4,7 @@ import re import pyblish.api -from ayon_core.hosts.max.api.action import SelectInvalidAction +from ayon_max.api.action import SelectInvalidAction from ayon_core.pipeline.publish import ( OptionalPyblishPluginMixin, @@ -39,6 +39,9 @@ class ValidateModelName(pyblish.api.InstancePlugin, families = ["model"] label = "Validate Model Name" actions = [SelectInvalidAction] + + settings_category = "max" + # defined by settings regex = r"(.*)_(?P.*)_(GEO)" # cache diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py b/server_addon/max/client/ayon_max/plugins/publish/validate_no_animation.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_no_animation.py index 4b2a18d606..26384954ca 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_no_animation.py @@ -5,7 +5,7 @@ from ayon_core.pipeline import ( PublishValidationError, OptionalPyblishPluginMixin ) -from ayon_core.hosts.max.api.action import SelectInvalidAction +from ayon_max.api.action import SelectInvalidAction def get_invalid_keys(obj): @@ -39,6 +39,8 @@ class ValidateNoAnimation(pyblish.api.InstancePlugin, label = "Validate No Animation" actions = [SelectInvalidAction] + settings_category = "max" + def process(self, instance): if not self.is_active(instance.data): return diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py b/server_addon/max/client/ayon_max/plugins/publish/validate_pointcloud.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_pointcloud.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_renderable_camera.py b/server_addon/max/client/ayon_max/plugins/publish/validate_renderable_camera.py similarity index 95% rename from client/ayon_core/hosts/max/plugins/publish/validate_renderable_camera.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_renderable_camera.py index ffd6b183fe..dc05771e1b 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_renderable_camera.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_renderable_camera.py @@ -4,7 +4,7 @@ from ayon_core.pipeline import ( PublishValidationError, OptionalPyblishPluginMixin) from ayon_core.pipeline.publish import RepairAction -from ayon_core.hosts.max.api.lib import get_current_renderer +from ayon_max.api.lib import get_current_renderer from pymxs import runtime as rt diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_renderer_redshift_proxy.py b/server_addon/max/client/ayon_max/plugins/publish/validate_renderer_redshift_proxy.py similarity index 96% rename from client/ayon_core/hosts/max/plugins/publish/validate_renderer_redshift_proxy.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_renderer_redshift_proxy.py index de3a806c85..66c69bc100 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_renderer_redshift_proxy.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_renderer_redshift_proxy.py @@ -3,7 +3,7 @@ import pyblish.api from ayon_core.pipeline import PublishValidationError from pymxs import runtime as rt from ayon_core.pipeline.publish import RepairAction -from ayon_core.hosts.max.api.lib import get_current_renderer +from ayon_max.api.lib import get_current_renderer class ValidateRendererRedshiftProxy(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_renderpasses.py b/server_addon/max/client/ayon_max/plugins/publish/validate_renderpasses.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/publish/validate_renderpasses.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_renderpasses.py index 394d3119c4..d0d47c6340 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_renderpasses.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_renderpasses.py @@ -7,7 +7,7 @@ from ayon_core.pipeline.publish import ( PublishValidationError, OptionalPyblishPluginMixin ) -from ayon_core.hosts.max.api.lib_rendersettings import RenderSettings +from ayon_max.api.lib_rendersettings import RenderSettings class ValidateRenderPasses(OptionalPyblishPluginMixin, @@ -21,6 +21,8 @@ class ValidateRenderPasses(OptionalPyblishPluginMixin, label = "Validate Render Passes" actions = [RepairAction] + settings_category = "max" + def process(self, instance): invalid = self.get_invalid(instance) if invalid: diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_resolution_setting.py b/server_addon/max/client/ayon_max/plugins/publish/validate_resolution_setting.py similarity index 98% rename from client/ayon_core/hosts/max/plugins/publish/validate_resolution_setting.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_resolution_setting.py index 5f6cd0a21d..9f7ec17dd9 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_resolution_setting.py +++ b/server_addon/max/client/ayon_max/plugins/publish/validate_resolution_setting.py @@ -7,7 +7,7 @@ from ayon_core.pipeline.publish import ( RepairAction, PublishValidationError ) -from ayon_core.hosts.max.api.lib import ( +from ayon_max.api.lib import ( reset_scene_resolution, imprint ) diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_scene_saved.py b/server_addon/max/client/ayon_max/plugins/publish/validate_scene_saved.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_scene_saved.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_scene_saved.py diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_tyflow_data.py b/server_addon/max/client/ayon_max/plugins/publish/validate_tyflow_data.py similarity index 100% rename from client/ayon_core/hosts/max/plugins/publish/validate_tyflow_data.py rename to server_addon/max/client/ayon_max/plugins/publish/validate_tyflow_data.py diff --git a/client/ayon_core/hosts/max/startup/startup.ms b/server_addon/max/client/ayon_max/startup/startup.ms similarity index 100% rename from client/ayon_core/hosts/max/startup/startup.ms rename to server_addon/max/client/ayon_max/startup/startup.ms diff --git a/client/ayon_core/hosts/max/startup/startup.py b/server_addon/max/client/ayon_max/startup/startup.py similarity index 88% rename from client/ayon_core/hosts/max/startup/startup.py rename to server_addon/max/client/ayon_max/startup/startup.py index 49a861bad0..1462cc93b7 100644 --- a/client/ayon_core/hosts/max/startup/startup.py +++ b/server_addon/max/client/ayon_max/startup/startup.py @@ -1,15 +1,13 @@ # -*- coding: utf-8 -*- import os import sys - +from ayon_max.api import MaxHost +from ayon_core.pipeline import install_host # this might happen in some 3dsmax version where PYTHONPATH isn't added # to sys.path automatically for path in os.environ["PYTHONPATH"].split(os.pathsep): if path and path not in sys.path: sys.path.append(path) -from ayon_core.hosts.max.api import MaxHost -from ayon_core.pipeline import install_host - host = MaxHost() install_host(host) diff --git a/server_addon/max/package.py b/server_addon/max/package.py index fb1f1b3050..ddd4e3b33e 100644 --- a/server_addon/max/package.py +++ b/server_addon/max/package.py @@ -1,3 +1,9 @@ name = "max" title = "Max" -version = "0.1.7" +version = "0.2.0" +client_dir = "ayon_max" + +ayon_required_addons = { + "core": ">0.3.2", +} +ayon_compatible_addons = {}