diff --git a/openpype/modules/sync_server/providers/abstract_provider.py b/openpype/modules/sync_server/providers/abstract_provider.py index a60595ba93..7cd42fb4fa 100644 --- a/openpype/modules/sync_server/providers/abstract_provider.py +++ b/openpype/modules/sync_server/providers/abstract_provider.py @@ -7,6 +7,8 @@ log = Logger().get_logger("SyncServer") @six.add_metaclass(abc.ABCMeta) class AbstractProvider: + CODE = '' + LABEL = '' def __init__(self, project_name, site_name, tree=None, presets=None): self.presets = None @@ -25,6 +27,38 @@ class AbstractProvider: (boolean) """ + @abc.abstractmethod + def set_editable_properties(self): + """ + Sets dictionary of editable properties with scopes. + + Example: + { 'credentials_url': {'scopes': [utils.EditableScopes.SYSTEM], + 'type': 'text'}} + """ + + @abc.abstractmethod + def get_editable_properties(self, scopes): + """ + Returns filtered list of editable properties + + Args: + scopes (list) of utils.EditableScopes (optional - filter on) + + Returns: + (dict) + """ + if not scopes: + return self._editable_properties + + editable = {} + for scope in scopes: + for key, properties in self._editable_properties.items(): + if scope in properties['scope']: + editable[key] = properties + + return editable + @abc.abstractmethod def upload_file(self, source_path, path, server, collection, file, representation, site, diff --git a/openpype/modules/sync_server/providers/gdrive.py b/openpype/modules/sync_server/providers/gdrive.py index b67e5a6cfa..f2c18a04a9 100644 --- a/openpype/modules/sync_server/providers/gdrive.py +++ b/openpype/modules/sync_server/providers/gdrive.py @@ -7,7 +7,7 @@ from .abstract_provider import AbstractProvider from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload from openpype.api import Logger from openpype.api import get_system_settings -from ..utils import time_function, ResumableError +from ..utils import time_function, ResumableError, EditableScopes import time @@ -42,9 +42,12 @@ class GDriveHandler(AbstractProvider): } } """ + CODE = 'gdrive' + LABEL = 'Google Drive' + FOLDER_STR = 'application/vnd.google-apps.folder' MY_DRIVE_STR = 'My Drive' # name of root folder of regular Google drive - CHUNK_SIZE = 2097152 # must be divisible by 256! + CHUNK_SIZE = 2097152 # must be divisible by 256! used for upload chunks def __init__(self, project_name, site_name, tree=None, presets=None): self.presets = None @@ -52,6 +55,8 @@ class GDriveHandler(AbstractProvider): self.project_name = project_name self.site_name = site_name + self._editable_properties = {} + self.presets = presets if not self.presets: log.info("Sync Server: There are no presets for {}.". @@ -73,6 +78,7 @@ class GDriveHandler(AbstractProvider): self._tree = tree self.active = True + self.set_editable_properties() def is_active(self): """ @@ -82,6 +88,17 @@ class GDriveHandler(AbstractProvider): """ return self.active + def set_editable_properties(self): + editable = { + 'credential_url': {'scope': [EditableScopes.PROJECT, + EditableScopes.LOCAL], + 'type': 'text'}, + + 'roots': {'scope': [EditableScopes.PROJECT], + 'type': 'dict'} + } + self._editable_properties = editable + def get_roots_config(self, anatomy=None): """ Returns root values for path resolving diff --git a/openpype/modules/sync_server/providers/lib.py b/openpype/modules/sync_server/providers/lib.py index 01a5d50ba5..f9c4309724 100644 --- a/openpype/modules/sync_server/providers/lib.py +++ b/openpype/modules/sync_server/providers/lib.py @@ -91,5 +91,5 @@ factory = ProviderFactory() # there is implementing 'GDriveHandler' class # 7 denotes number of files that could be synced in single loop - learned by # trial and error -factory.register_provider('gdrive', GDriveHandler, 7) -factory.register_provider('local_drive', LocalDriveHandler, 50) +factory.register_provider(GDriveHandler.CODE, GDriveHandler, 7) +factory.register_provider(LocalDriveHandler.CODE, LocalDriveHandler, 50) diff --git a/openpype/modules/sync_server/providers/local_drive.py b/openpype/modules/sync_server/providers/local_drive.py index 1f4fca80eb..2a96094f22 100644 --- a/openpype/modules/sync_server/providers/local_drive.py +++ b/openpype/modules/sync_server/providers/local_drive.py @@ -7,22 +7,37 @@ import time from openpype.api import Logger, Anatomy from .abstract_provider import AbstractProvider +from ..utils import EditableScopes + log = Logger().get_logger("SyncServer") class LocalDriveHandler(AbstractProvider): + CODE = 'local_drive' + LABEL = 'Local drive' + """ Handles required operations on mounted disks with OS """ def __init__(self, project_name, site_name, tree=None, presets=None): self.presets = None self.active = False self.project_name = project_name self.site_name = site_name + self._editable_properties = {} self.active = self.is_active() + self.set_editable_properties() def is_active(self): return True + def set_editable_properties(self): + editable = { + 'roots': {'scope': [EditableScopes.PROJECT, + EditableScopes.LOCAL], + 'type': 'dict'} + } + self._editable_properties = editable + def upload_file(self, source_path, target_path, server, collection, file, representation, site, overwrite=False, direction="Upload"): diff --git a/openpype/modules/sync_server/sync_server_module.py b/openpype/modules/sync_server/sync_server_module.py index b50bf19dca..e29861c20c 100644 --- a/openpype/modules/sync_server/sync_server_module.py +++ b/openpype/modules/sync_server/sync_server_module.py @@ -340,18 +340,6 @@ class SyncServerModule(PypeModule, ITrayModule): return self._get_enabled_sites_from_settings(sync_settings) - def get_configurable_items_for_site(self, project_name, site_name): - """ - Returns list of items that should be configurable by User - - Returns: - (list of dict) - [{key:"root", label:"root", value:"valueFromSettings"}] - """ - # if project_name is None: ..for get_default_project_settings - # return handler.get_configurable_items() - pass - def get_active_site(self, project_name): """ Returns active (mine) site for 'project_name' from settings @@ -402,6 +390,32 @@ class SyncServerModule(PypeModule, ITrayModule): return remote_site + def get_configurable_items(self): + pass + + def get_configurable_items_for_site(self, project_name, site_name): + """ + Returns list of items that should be configurable by User + + Returns: + (list of dict) + [{key:"root", label:"root", value:"valueFromSettings"}] + """ + # sites = set(self.get_active_sites(project_name), + # self.get_remote_sites(project_name)) + # for site in sites: + # if site_name + + def _get_configurable_items_for_project(self, project_name): + from .providers import lib + sites = set(self.get_active_sites(project_name), + self.get_remote_sites(project_name)) + editable = {} + for site in sites: + provider_name = self.get_provider_for_site(project_name, site) + + + def reset_timer(self): """ Called when waiting for next loop should be skipped. diff --git a/openpype/modules/sync_server/utils.py b/openpype/modules/sync_server/utils.py index fa6e63b029..d4fc29ff8a 100644 --- a/openpype/modules/sync_server/utils.py +++ b/openpype/modules/sync_server/utils.py @@ -33,3 +33,9 @@ def time_function(method): return result return timed + + +class EditableScopes: + SYSTEM = 0 + PROJECT = 1 + LOCAL = 2 diff --git a/openpype/settings/entities/__init__.py b/openpype/settings/entities/__init__.py index f76a915225..2c71b622ee 100644 --- a/openpype/settings/entities/__init__.py +++ b/openpype/settings/entities/__init__.py @@ -101,7 +101,8 @@ from .enum_entity import ( BaseEnumEntity, EnumEntity, AppsEnumEntity, - ToolsEnumEntity + ToolsEnumEntity, + ProvidersEnum ) from .list_entity import ListEntity @@ -149,6 +150,7 @@ __all__ = ( "EnumEntity", "AppsEnumEntity", "ToolsEnumEntity", + "ProvidersEnum", "ListEntity", diff --git a/openpype/settings/entities/enum_entity.py b/openpype/settings/entities/enum_entity.py index 693305cb1e..a5492cd727 100644 --- a/openpype/settings/entities/enum_entity.py +++ b/openpype/settings/entities/enum_entity.py @@ -217,3 +217,49 @@ class ToolsEnumEntity(BaseEnumEntity): if key in self.valid_keys: new_value.append(key) self._current_value = new_value + + +class ProvidersEnum(BaseEnumEntity): + schema_types = ["providers-enum"] + + def _item_initalization(self): + self.multiselection = False + self.value_on_not_set = "" + self.enum_items = [] + self.valid_keys = set() + self.valid_value_types = (str, ) + self.placeholder = None + + def _get_enum_values(self): + # from openpype.modules.sync_server.providers import lib as lib_providers + # + # providers = lib_providers.factory.providers + # + # valid_keys = set() + # enum_items = [] + # for provider_code, provider_info in providers.items(): + # provider, _ = provider_info + # enum_items.append({provider_code: provider.LABEL}) + # valid_keys.add(provider_code) + valid_keys = set() + enum_items = [] + if not valid_keys: + enum_items.append({'': 'N/A'}) + valid_keys.add('') + + return enum_items, valid_keys + + def set_override_state(self, *args, **kwargs): + super(ProvidersEnum, self).set_override_state(*args, **kwargs) + + self.enum_items, self.valid_keys = self._get_enum_values() + + value_on_not_set = list(self.valid_keys)[0] + if self._current_value is NOT_SET: + self._current_value = value_on_not_set + + self.value_on_not_set = value_on_not_set + + +# class ActiveSiteEnum +# class RemoteSiteEnum \ No newline at end of file diff --git a/openpype/settings/entities/schemas/system_schema/schema_modules.json b/openpype/settings/entities/schemas/system_schema/schema_modules.json index 878958b12d..d1b498bb86 100644 --- a/openpype/settings/entities/schemas/system_schema/schema_modules.json +++ b/openpype/settings/entities/schemas/system_schema/schema_modules.json @@ -85,11 +85,32 @@ "label": "Site Sync", "collapsible": true, "checkbox_key": "enabled", - "children": [{ - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }] + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "dict-modifiable", + "collapsible": true, + "key": "sites", + "label": "Sites", + "collapsible_key": false, + "is_file": true, + "object_type": + { + "type": "dict", + "children": [ + { + "type": "providers-enum", + "key": "provider", + "label": "Provider" + } + ] + } + } + ] },{ "type": "dict", "key": "deadline",