From 51b8a2227f3e00b36001ffd34a474cad6c83e542 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Sep 2021 18:22:43 +0200 Subject: [PATCH 1/8] Committed changes from SyncServer: Dropbox Provider #1979 Useful for future, PR wasnt merged yet --- .../providers/abstract_provider.py | 3 +- .../sync_server/providers/gdrive.py | 9 ++- .../schema_project_syncserver.json | 75 +++++++++++++++---- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/abstract_provider.py b/openpype/modules/default_modules/sync_server/providers/abstract_provider.py index 7fd25b98525..37e0fe94218 100644 --- a/openpype/modules/default_modules/sync_server/providers/abstract_provider.py +++ b/openpype/modules/default_modules/sync_server/providers/abstract_provider.py @@ -80,7 +80,8 @@ def upload_file(self, source_path, path, representation (dict): complete repre containing 'file' site (str): site name Returns: - (string) file_id of created file, raises exception + (string) file_id of created/modified file , + throws FileExistsError, FileNotFoundError exceptions """ pass diff --git a/openpype/modules/default_modules/sync_server/providers/gdrive.py b/openpype/modules/default_modules/sync_server/providers/gdrive.py index f1ec0b6a0d0..0aabd9fbcd5 100644 --- a/openpype/modules/default_modules/sync_server/providers/gdrive.py +++ b/openpype/modules/default_modules/sync_server/providers/gdrive.py @@ -61,7 +61,6 @@ class GDriveHandler(AbstractProvider): 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 self.active = False self.project_name = project_name self.site_name = site_name @@ -74,7 +73,13 @@ def __init__(self, project_name, site_name, tree=None, presets=None): format(site_name)) return - cred_path = self.presets.get("credentials_url", {}).\ + provider_presets = self.presets.get(self.CODE) + if not provider_presets: + msg = "Sync Server: No provider presets for {}".format(self.CODE) + log.info(msg) + return + + cred_path = self.presets[self.CODE].get("credentials_url", {}).\ get(platform.system().lower()) or '' if not os.path.exists(cred_path): msg = "Sync Server: No credentials for gdrive provider " + \ diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json index cb2cc9c9d1e..75574ed703c 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_syncserver.json @@ -47,20 +47,67 @@ { "type": "dict", "children": [ - { - "type": "path", - "key": "credentials_url", - "label": "Credentials url", - "multiplatform": true - }, - { - "type": "dict-modifiable", - "key": "root", - "label": "Roots", - "collapsable": false, - "collapsable_key": false, - "object_type": "text" - } + { + "type": "dict", + "key": "gdrive", + "label": "Google Drive", + "collapsible": true, + "children": [ + { + "type": "path", + "key": "credentials_url", + "label": "Credentials url", + "multiplatform": true + } + ] + }, + { + "type": "dict", + "key": "sftp", + "label": "SFTP", + "collapsible": true, + "children": [ + { + "type": "text", + "key": "sftp_host", + "label": "SFTP host" + }, + { + "type": "number", + "key": "sftp_port", + "label": "SFTP port" + }, + { + "type": "text", + "key": "sftp_user", + "label": "SFTP user" + }, + { + "type": "text", + "key": "sftp_pass", + "label": "SFTP pass" + }, + { + "type": "path", + "key": "sftp_key", + "label": "SFTP user ssh key", + "multiplatform": true + }, + { + "type": "text", + "key": "sftp_key_pass", + "label": "SFTP user ssh key password" + } + ] + }, + { + "type": "dict-modifiable", + "key": "root", + "label": "Roots", + "collapsable": false, + "collapsable_key": false, + "object_type": "text" + } ] } } From 99f6d6617b01d882165bc99e764c4faa9a8cdefe Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 24 Sep 2021 18:45:51 +0200 Subject: [PATCH 2/8] Implemented SFTP provider for Site Sync --- .../sync_server/providers/lib.py | 2 + .../sync_server/providers/resources/sftp.png | Bin 0 -> 2105 bytes .../sync_server/providers/sftp.py | 450 ++++++++++++++++++ pyproject.toml | 1 + 4 files changed, 453 insertions(+) create mode 100644 openpype/modules/default_modules/sync_server/providers/resources/sftp.png create mode 100644 openpype/modules/default_modules/sync_server/providers/sftp.py diff --git a/openpype/modules/default_modules/sync_server/providers/lib.py b/openpype/modules/default_modules/sync_server/providers/lib.py index 463e49dd4d9..c0dd7cee941 100644 --- a/openpype/modules/default_modules/sync_server/providers/lib.py +++ b/openpype/modules/default_modules/sync_server/providers/lib.py @@ -1,5 +1,6 @@ from .gdrive import GDriveHandler from .local_drive import LocalDriveHandler +from .sftp import SFTPHandler class ProviderFactory: @@ -112,3 +113,4 @@ class and batch limit. # trial and error factory.register_provider(GDriveHandler.CODE, GDriveHandler, 7) factory.register_provider(LocalDriveHandler.CODE, LocalDriveHandler, 50) +factory.register_provider(SFTPHandler.CODE, SFTPHandler, 20) diff --git a/openpype/modules/default_modules/sync_server/providers/resources/sftp.png b/openpype/modules/default_modules/sync_server/providers/resources/sftp.png new file mode 100644 index 0000000000000000000000000000000000000000..56c7a5cca3628fac9229cc73a65b65d27878c7c0 GIT binary patch literal 2105 zcmbVN3v3is6rB<+g;@Q5TZgN1jMKTYS1^^?NUrZ;wH26=DqXo zJ@?%E?pxd3R9`x}ax{ivrJ;sk1ij1cr=%GDpUe2Kqt__Cp~b{7N0t2)WqanNF|0Tu zM`KnjJf8=e;t(WFgpRDDBQ%E1nv>N9uoPOj2otjEC$4_6hrngYPb_kU>9Af4lX63c z0T*^OMM1|>;FE|sv+-G39vM)eCE!^lrJ8)!Pvq?KXlzeY1fGLfOZ`N^c8JHq&3LV5 zK-}%1NkG#a&Mkh?m=CF@C8z*~f_?(Y;*e#D7d@hjkvJ#maXD!cdYoR;D~c@1 zaV!vAlF!RQ=ivUJ2HNc8+xrJjf}{at<2F4`^aubTv1l*DkWg|mr08MeB;)bWUch*L z94xR|V94k&3aO!1ZB`Pp=#pG+QQ$lz&Crmfp_3)OZrVvYeJ<9;xq#CJ+;+j|YKU); zO_bgC{1I9RpU;m{GM+0NUI6xS@DsqU11J&sX?Yku?#pw2esrd2`)?*r|#hB7GfO zeYP~>EdMB%TwYch)9}cTs z6U<$K=lY^YFFw7udfbm?t-n3EVQhQb*mdqrEz4UUxIi42D|YX@s!pnW{MpLH$i}_N z%bn#@8?oQZW-V$Jj;<#+|JqkF=C45WisFj$l~-T?vu*6OsuE`-z4M`s6Ty|w`h72d z)WR(OrK-d_(;4aP+H1V~`Q$U?{9CR+icXi`a6Q)i=$5%Hh;!wkgH->`*Fe|C=`9m~ zdgkHks9%}(P6V<&jgmWJK><-NiN7rP;f8J$Z88-$$2p z&e+|rU5l?ieXxB>;t+SauD|pBW$s=%(9znvbME->_I>%rlyl#{R1^+edGYwRQ)>?# mu1Jljk7vt{O}wPud;vQW&wM&zUgmrIau3xt1-I9{}".format(source_path, target_path)) + conn = self._get_conn() + conn.put(source_path, target_path) + + def download_file(self, source_path, target_path, + server, collection, file, representation, site, + overwrite=False): + """ + Downloads single file from 'source_path' (remote) to 'target_path'. + It creates all folders on the local_path if are not existing. + By default existing file on 'target_path' will trigger an exception + + Args: + source_path (string): absolute path on provider + target_path (string): absolute path with or without name of a file + overwrite (boolean): replace existing file + + arguments for saving progress: + server (SyncServer): server instance to call update_db on + collection (str): name of collection + file (dict): info about uploaded file (matches structure from db) + representation (dict): complete repre containing 'file' + site (str): site name + + Returns: + (string) file_id of created/modified file , + throws FileExistsError, FileNotFoundError exceptions + """ + if not self.file_path_exists(source_path): + raise FileNotFoundError("Source file {} doesn't exist." + .format(source_path)) + + if os.path.isfile(target_path): + if not overwrite: + raise ValueError("File {} exists, set overwrite". + format(target_path)) + + thread = threading.Thread(target=self._download, + args=(source_path, target_path)) + thread.start() + self._mark_progress(collection, file, representation, server, + site, source_path, target_path, "download") + + return os.path.basename(target_path) + + def _download(self, source_path, target_path): + print("downloading {}->{}".format(source_path, target_path)) + conn = self._get_conn() + conn.get(source_path, target_path) + + def delete_file(self, path): + """ + Deletes file from 'path'. Expects path to specific file. + + Args: + path: absolute path to particular file + + Returns: + None + """ + if not self.file_path_exists(path): + raise FileNotFoundError("File {} to be deleted doesn't exist." + .format(path)) + self.conn.remove(path) + + def list_folder(self, folder_path): + """ + List all files and subfolders of particular path non-recursively. + + Args: + folder_path (string): absolut path on provider + Returns: + (list) + """ + return list(pysftp.path_advance(folder_path)) + + def folder_path_exists(self, file_path): + """ + Checks if path from 'file_path' exists. If so, return its + folder id. + Args: + file_path (string): path with / as a separator + Returns: + (string) folder id or False + """ + if not file_path: + return False + + return self.conn.isdir(file_path) + + def file_path_exists(self, file_path): + """ + Checks if 'file_path' exists on GDrive + + Args: + file_path (string): separated by '/', from root, with file name + Returns: + (dictionary|boolean) file metadata | False if not found + """ + if not file_path: + return False + + return self.conn.isfile(file_path) + + @classmethod + def get_presets(cls): + """ + Get presets for this provider + Returns: + (dictionary) of configured sites + """ + provider_presets = None + try: + provider_presets = ( + get_system_settings()["modules"] + ["sync_server"] + ["providers"] + ["sftp"] + ) + except KeyError: + log.info(("Sync Server: There are no presets for SFTP " + + "provider."). + format(str(provider_presets))) + return + return provider_presets + + def _get_conn(self): + """ + Returns fresh sftp connection. + + It seems that connection cannot be cached into self.conn, at least + for get and put which run in separate threads. + + Returns: + pysftp.Connection + """ + cnopts = pysftp.CnOpts() + cnopts.hostkeys = None + + conn_params = { + 'host': self.sftp_host, + 'port': self.sftp_port, + 'username': self.sftp_user, + 'cnopts': cnopts + } + if self.sftp_pass and self.sftp_pass.strip(): + conn_params['password'] = self.sftp_pass + if self.sftp_key: + conn_params['private_key'] = self.sftp_key + if self.sftp_key_pass: + conn_params['private_key_pass'] = self.sftp_key_pass + + return pysftp.Connection(**conn_params) + + def _mark_progress(self, collection, file, representation, server, site, + source_path, target_path, direction): + """ + Updates progress field in DB by values 0-1. + + Compares file sizes of source and target. + """ + pass + if direction == "upload": + source_file_size = os.path.getsize(source_path) + else: + source_file_size = self.conn.stat(source_path).st_size + + target_file_size = 0 + last_tick = status_val = None + while source_file_size != target_file_size: + if not last_tick or \ + time.time() - last_tick >= server.LOG_PROGRESS_SEC: + status_val = target_file_size / source_file_size + last_tick = time.time() + log.debug(direction + "ed %d%%." % int(status_val * 100)) + server.update_db(collection=collection, + new_file_id=None, + file=file, + representation=representation, + site=site, + progress=status_val + ) + try: + if direction == "upload": + target_file_size = self.conn.stat(target_path).st_size + else: + target_file_size = os.path.getsize(target_path) + except FileNotFoundError: + pass + time.sleep(0.5) diff --git a/pyproject.toml b/pyproject.toml index e376986606f..6ad090f30f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,7 @@ jinxed = [ python3-xlib = { version="*", markers = "sys_platform == 'linux'"} enlighten = "^1.9.0" slack-sdk = "^3.6.0" +pysftp = "^0.2.9" [tool.poetry.dev-dependencies] flake8 = "^3.7" From 13945937d2172de77580f76669a8af3ecd979828 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 27 Sep 2021 13:25:32 +0200 Subject: [PATCH 3/8] Added pysftp library to poetry --- poetry.lock | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index e011b781c91..f3b26c2ba12 100644 --- a/poetry.lock +++ b/poetry.lock @@ -144,6 +144,22 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pytz = ">=2015.7" +[[package]] +name = "bcrypt" +version = "3.2.0" +description = "Modern password hashing for your software and your servers" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.1" +six = ">=1.4.1" + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + [[package]] name = "blessed" version = "1.18.0" @@ -704,6 +720,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pyparsing = ">=2.0.2" +[[package]] +name = "paramiko" +version = "2.7.2" +description = "SSH2 protocol library" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +bcrypt = ">=3.1.3" +cryptography = ">=2.5" +pynacl = ">=1.0.1" + +[package.extras] +all = ["pyasn1 (>=0.1.7)", "pynacl (>=1.0.1)", "bcrypt (>=3.1.3)", "invoke (>=1.3)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"] +ed25519 = ["pynacl (>=1.0.1)", "bcrypt (>=3.1.3)"] +gssapi = ["pyasn1 (>=0.1.7)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"] +invoke = ["invoke (>=1.3)"] + [[package]] name = "parso" version = "0.8.2" @@ -888,6 +923,22 @@ srv = ["dnspython (>=1.16.0,<1.17.0)"] tls = ["ipaddress"] zstd = ["zstandard"] +[[package]] +name = "pynacl" +version = "1.4.0" +description = "Python binding to the Networking and Cryptography (NaCl) library" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +cffi = ">=1.4.1" +six = "*" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] + [[package]] name = "pynput" version = "1.7.3" @@ -977,6 +1028,17 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "pysftp" +version = "0.2.9" +description = "A friendly face on SFTP" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +paramiko = ">=1.17" + [[package]] name = "pytest" version = "6.2.4" @@ -1466,7 +1528,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" python-versions = "3.7.*" -content-hash = "8875d530ae66f9763b5b0cb84d9d35edc184ef5c141b63d38bf1ff5a1226e556" +content-hash = "ff2bfa35a7304378917a0c25d7d7af9f81a130288d95789bdf7429f071e80b69" [metadata.files] acre = [] @@ -1553,6 +1615,15 @@ babel = [ {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, ] +bcrypt = [ + {file = "bcrypt-3.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6"}, + {file = "bcrypt-3.2.0-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7"}, + {file = "bcrypt-3.2.0-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1"}, + {file = "bcrypt-3.2.0-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d"}, + {file = "bcrypt-3.2.0-cp36-abi3-win32.whl", hash = "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55"}, + {file = "bcrypt-3.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34"}, + {file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"}, +] blessed = [ {file = "blessed-1.18.0-py2.py3-none-any.whl", hash = "sha256:5b5e2f0563d5a668c282f3f5946f7b1abb70c85829461900e607e74d7725106e"}, {file = "blessed-1.18.0.tar.gz", hash = "sha256:1312879f971330a1b7f2c6341f2ae7e2cbac244bfc9d0ecfbbecd4b0293bc755"}, @@ -1582,24 +1653,36 @@ cffi = [ {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed"}, + {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55"}, {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05"}, + {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc"}, {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f"}, + {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76"}, {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333"}, + {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7"}, {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, @@ -1935,6 +2018,10 @@ packaging = [ {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] +paramiko = [ + {file = "paramiko-2.7.2-py2.py3-none-any.whl", hash = "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898"}, + {file = "paramiko-2.7.2.tar.gz", hash = "sha256:7f36f4ba2c0d81d219f4595e35f70d56cc94f9ac40a6acdf51d6ca210ce65035"}, +] parso = [ {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, @@ -2006,9 +2093,13 @@ protobuf = [ {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"}, {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"}, {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"}, + {file = "protobuf-3.17.3-cp38-cp38-win32.whl", hash = "sha256:59e5cf6b737c3a376932fbfb869043415f7c16a0cf176ab30a5bbc419cd709c1"}, + {file = "protobuf-3.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ebcb546f10069b56dc2e3da35e003a02076aaa377caf8530fe9789570984a8d2"}, {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"}, {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"}, {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"}, + {file = "protobuf-3.17.3-cp39-cp39-win32.whl", hash = "sha256:a38bac25f51c93e4be4092c88b2568b9f407c27217d3dd23c7a57fa522a17554"}, + {file = "protobuf-3.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:85d6303e4adade2827e43c2b54114d9a6ea547b671cb63fafd5011dc47d0e13d"}, {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"}, {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"}, ] @@ -2144,6 +2235,26 @@ pymongo = [ {file = "pymongo-3.11.4-py2.7-macosx-10.14-intel.egg", hash = "sha256:506a6dab4c7ffdcacdf0b8e70bd20eb2e77fa994519547c9d88d676400fcad58"}, {file = "pymongo-3.11.4.tar.gz", hash = "sha256:539d4cb1b16b57026999c53e5aab857fe706e70ae5310cc8c232479923f932e6"}, ] +pynacl = [ + {file = "PyNaCl-1.4.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff"}, + {file = "PyNaCl-1.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514"}, + {file = "PyNaCl-1.4.0-cp27-cp27m-win32.whl", hash = "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574"}, + {file = "PyNaCl-1.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80"}, + {file = "PyNaCl-1.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7"}, + {file = "PyNaCl-1.4.0-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122"}, + {file = "PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d"}, + {file = "PyNaCl-1.4.0-cp35-abi3-win32.whl", hash = "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634"}, + {file = "PyNaCl-1.4.0-cp35-abi3-win_amd64.whl", hash = "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6"}, + {file = "PyNaCl-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4"}, + {file = "PyNaCl-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25"}, + {file = "PyNaCl-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4"}, + {file = "PyNaCl-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6"}, + {file = "PyNaCl-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f"}, + {file = "PyNaCl-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f"}, + {file = "PyNaCl-1.4.0-cp38-cp38-win32.whl", hash = "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96"}, + {file = "PyNaCl-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420"}, + {file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"}, +] pynput = [ {file = "pynput-1.7.3-py2.py3-none-any.whl", hash = "sha256:fea5777454f896bd79d35393088cd29a089f3b2da166f0848a922b1d5a807d4f"}, {file = "pynput-1.7.3-py3.8.egg", hash = "sha256:6626e8ea9ca482bb5628a7169e1193824e382c4ad3053e40f4f24f41ee7b41c9"}, @@ -2212,6 +2323,9 @@ pyqt5-sip = [ pyrsistent = [ {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, ] +pysftp = [ + {file = "pysftp-0.2.9.tar.gz", hash = "sha256:fbf55a802e74d663673400acd92d5373c1c7ee94d765b428d9f977567ac4854a"}, +] pytest = [ {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, From 12c9d42ce20ed6519e160731627ec5436432898f Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 30 Sep 2021 15:59:09 +0200 Subject: [PATCH 4/8] Fix - safer handling of no presets --- .../modules/default_modules/sync_server/providers/sftp.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index 3b480be8b6e..c7a6e9a6203 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -42,17 +42,18 @@ def __init__(self, project_name, site_name, tree=None, presets=None): self.project_name = project_name self.site_name = site_name self.root = None + self.conn = None self.presets = presets if not self.presets: - log.info("Sync Server: There are no presets for {}.". - format(site_name)) + log.warning("Sync Server: There are no presets for {}.". + format(site_name)) return provider_presets = self.presets.get(self.CODE) if not provider_presets: msg = "Sync Server: No provider presets for {}".format(self.CODE) - log.info(msg) + log.warning(msg) return # store to instance for reconnect From 772492ecf40d679db297ae0dc3e90632ef469d90 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 30 Sep 2021 16:22:37 +0200 Subject: [PATCH 5/8] Revert unwanted --- repos/avalon-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/avalon-core b/repos/avalon-core index 2aed427da67..a0f0356e5c6 160000 --- a/repos/avalon-core +++ b/repos/avalon-core @@ -1 +1 @@ -Subproject commit 2aed427da67f63806455e3fb0d91b80cda38b685 +Subproject commit a0f0356e5c65a25532fe73caa4d471f95d386d49 From 1549deba939877b876a4363f8c542200c5a2b8ea Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 30 Sep 2021 16:25:25 +0200 Subject: [PATCH 6/8] Revert unwanted second try --- repos/avalon-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/avalon-core b/repos/avalon-core index a0f0356e5c6..8aee68fa10a 160000 --- a/repos/avalon-core +++ b/repos/avalon-core @@ -1 +1 @@ -Subproject commit a0f0356e5c65a25532fe73caa4d471f95d386d49 +Subproject commit 8aee68fa10ab4d79be1a91e7728a609748e7c3c6 From dbfc44ec6d36c7488ff68531c8884cc5e576bb0f Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 1 Oct 2021 18:55:46 +0200 Subject: [PATCH 7/8] Added documentation --- .../site_sync_project_sftp_settings.png | Bin 0 -> 16385 bytes ...e_sync_sftp_project_setting_not_forced.png | Bin 0 -> 21718 bytes .../assets/site_sync_sftp_settings_local.png | Bin 0 -> 7415 bytes website/docs/assets/site_sync_sftp_system.png | Bin 0 -> 13112 bytes website/docs/module_site_sync.md | 30 ++++++++++++++++++ 5 files changed, 30 insertions(+) create mode 100644 website/docs/assets/site_sync_project_sftp_settings.png create mode 100644 website/docs/assets/site_sync_sftp_project_setting_not_forced.png create mode 100644 website/docs/assets/site_sync_sftp_settings_local.png create mode 100644 website/docs/assets/site_sync_sftp_system.png diff --git a/website/docs/assets/site_sync_project_sftp_settings.png b/website/docs/assets/site_sync_project_sftp_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..79267ba1d77e682c8fa53e3164c6509575fa5894 GIT binary patch literal 16385 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

>HeTp&T@%pixR$fb_oca+tpcCM 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 literal 0 HcmV?d00001 diff --git a/website/docs/assets/site_sync_sftp_project_setting_not_forced.png b/website/docs/assets/site_sync_sftp_project_setting_not_forced.png new file mode 100644 index 0000000000000000000000000000000000000000..7bd735b46c8d3dce973fd2e5b288fd333f3a0c73 GIT binary patch literal 21718 zcmbTdcRbr|-#4DN%BhsLs;Ht1wbe@P(xEj1Ss)GiVEeS4nQ?|Sb0x$gUV?&tZ#k@-CwIbO%-^B$kiH%jN3+WB)=&w)Uo^G}~V z)CGY~Yk)wfM*g4$-Z@r?y9_*>^3YXN1(gq6TLoUwIH+i;fIy$(7>;eu0hJl5;G>KEM_JE(WR z@OkslMaR>(U!Cir{lV08NW~phwBTkZ12$SbZY2-m%ONwkDIw%KJeW!~6_CsE_AanH zafo=flLr}7ku+S#ZZ&)wN*<{$aLzWZ*~__g((hSdRG5F{8FbwKEa(OJ&ebxHL1b>W zg;_1pIubJ=;5qf{1vp8{W{d_pS=FiKCGE8~_H}XQ`OA6eQD2|g-VVZF%N?wJtJ`ti zB*!3df@dY|QGCrRD!6DV9umBKF=)j5emAA|X1e>N(Vhbvd;&8?xe}!A(du3jZTX9? z3|55;ZWhHXa26ZyShVb((8DPnOUDitMn@sR``_tchnEtmOYpsIK5Bs1=12JI(XiM` z0riAu)-%`R#2Dd^y-V4qPL@Q7O{^IA1XK1?nWc#tZ)y%BwM%3VyVO&DP6kM0e#k2B zN4K=vABBoh9SmB?ii%`BWp=w~=fo6+(}Nt6TAZ}8UPo(ea(g6ZOlCUFP^AinA|729 z-P@D3M-7Wmi%j97WYW>~QLr>|``R)thKLfx5eIk3EL%s}1XP1o!x3g}hj(xVWeEL1 zDR|$jj1eH6p!_${bj`93R(mL~(NwWDelgc7y|g_xtI?Ek!nm_fqdmeG4HG~Z#I^p+ zNWEHc)Op}I-AK1L5^xfQx(m&Kq#w2#QoYqymR}4~DUj*bR|^hFWCDD5ug@zeHws0m zgRzsNPe=}gq@c*lW9kf&;+{Wgh(^*?G1M?6@5TooaN- zIa%01kNdYFL`G5@f9zAUl|Q}IxA*-ULH}Xl&OPh=SYvB3A6EgMV zdFGWzJ0}8HIrOm0t=WDoVCPQTl3H9DD=+Rq?1%s_M=>|d5>EEVNs74+GV41@+O0?M z-NONXJwz*eDwXm>?!=^+JPJpmn5mh|oXlyfm&Rv*TJ5EFXy={;4p@IF5E9xHoo}=&S7B{7I zm#yHJR62*egw7Y8Fz^9Ie9IwE^;PlGAbL`P_v1@L}4}zwHpQN`3?(8cB@BSIfC0lxnPHC(h zS~i9FqKVv*6v}l)LGOKXD43FaVSX;OaCK9sI&Gg%W8hG@jF!WHMN-s?zEFYjK`(Q%7 zA&(SkqCNJxpuEq=$Jd-k-^Y759QxRtDAu0rpQQ}qsL8XlKRMyQtP2jU!Kktx%H^Vk z6_pLbXmLTSQ({X$z<9?S^7npUK;wqkOc#)9Bm9o6boH?$dY%(eq{EfB;x(Ztb-&j_-K9S0L5K>zZ8YKnLBp-%6(Ek9QnQ8ftMX zKi=o~Hy$1wIaLRlivHu@RcTi$z5JOX_ssjqEHQ<;6LE3m56P5@N8W+C$_ltv3;Ec| z?x-^$5ToT`WZnQ1{9TXgRTI0<&)*M-a+V=QONRT?wt^kEBQANx3J*VJ$+c8|LDkh^ z5@IVVEWC5qeD{7Z!m1#^(E0g_@uNp)E!&{IuE;zT_P08~xa_;^ z6DAMKuaq|z#+?}rk6LI6z<5%Vxph!WOq{SQPlcLs4iP?LW90WvJ+zH(?CQwYpYr}V z^8%9jO8zO(eUxBnmHxCqy5SGH{L$!f+0TUOlT)1({(cED;na2--U<`ZD#Ss6|J>_D z)B2mo?TD<_9k@)p!cg^^MuzC|fKScOmPG$XvC$DSX|;txZ0sy-BqE(8?708}S-15m z3m1(tXr%KA`>FIWV(?8?8W}EQRwv(~wLBy@8>d`CWKW93i?;{TIR_aNy$4sEZT#Kp ze?ml>e+D7%G8!3}I3Y8RA*Bh$@wnTGv(1Zje%B{=6PtAHL-3CtnO=V8Shwc&zD&+* z`I>4!gZZyn%8_oq$4XV1ViM&jV-virSL676s%9pjek5U`Hew$!e1YkBeG`ubc_54Y5q)P z6CJ}YDYWjShnqG?G$e6Z{Yoc&74rwye43&5v$R+~ZM-Jl(t5(erp`?(T*xq2%R%s| zeL$Hv^?(?{dU8U=YVtEvUTtEm!!a=&5}Q{*Am42!4gT@0cs^mTl*}=w(|X-^BvV{H zt2%D;irtAxi2l&jR1#P`z;U-%%YJJ%K;16;GTYi`yQaiVDwxf*nNOH4x1ZVq4^`E< zaaZ6+%frtScp9ihU6t*`u8@J@OXQnP@ca)8G`uN;{)x(v@!<(2YpH7UTbcEg z%)OJFY$@BbGReXfB-)$v9oX3I3Sm~CLR-5?IW^XzoSJWe z(l$P!#+H0=-5hI7Og}rbELQ> ze&BZ<@2ZHUNlctJPwc{X8A4Ap?4^?l2Z9gkzVDuVMpE3y9x)HJ)082asGoJtmdGy? z7@D7bubbMzA1sgzZ+ZBNTb#e< z=aQTLTD$Bw3hxz6L4i?g0RwchlzBioe1;lu5Kz&%4eZEp7z1Xfd{%mXgJL&%9t6tm z!Els+3(FgoJFfh3zEhCfAop%T%-G8NTl%KDrD!FELd=Pk*3s(371HxFvLfa;@J9TH z>$gbU0WHXvR>$E>4+s^nF8c+!g*XqXmi;_pJ`8#tl3&XGNz0Y3bgY-5AD2+2%RFE+ zf7V}YIQ8geMa4VnQ5DoBG{q&O?_RoCHI-H7?GgFp!%UpnrQpqYX!J4D;0+MydPy@? zW|~?H%?YmcNsdkW2vM@r=>Pa)JWgO#Ik1;xZijq-5;%UPHtt@wt-adr27|Md!}>kA z$w8Tv%GxQ5Uofho(btGKi3}a-8D#3Uqp%jq&Fq8S^n`phAhT)ACgwdaU?u)2WJ!rJ3n_J-F=Q=FBxL}^pfI!=sV-?ooKd37BkWuF<4F_mc*BMcA6~0Hm&C}#%$xq4 zyCbMPJ0vBd*X0Z-llo(Zkq!hBzjpp}odf_CCl8EIgFt`Y|F`3uqJtAIqaFz?<34*L zFL2o(VgE9AWQQL7`Ta!@rEPh~BWEQ*)S`U~YZBMOAPDA@Q7)iUsFXh*3vCd+H|W3Yb_C&Sk1 z;oD{BidE;G*pj>zw;hgB4{lQOtD-P&qcXQ=hKfliSPwqyyiJFEdShJONn$Jc&BWN= zbXCQg&CKCfPVa))nS+^;II21oCes7a#&^RQL7-jqXF&}Sk*T7|M%Zf};}4p~evp_o z2dwufpHRxy-e3yIPIWXrk&n?YvCw`hb4K*rw^s{-`j$Epcwv+Lz6sI2WfA!Bp2lab zz-q75;JKt!+fyNoZw^ArpH81NXaZxyglD0Mux^9 zKTMiWf5UBI^%xq=A&e%MNbQ82)9*V+xor#yF)T?vv9CnPZ#>@dX=q(b`_d}6B^v}b zdzZSBwtUI7w%Y3hUp`vVAM4u_lrJ@SRx1!-5kmsap+0@;M!e?)6;!HI&#MKGJB@^d z7o%;u2P~U(2VI_L>-pX^&nqb%dx+=nEj#!XuVL|XO{j-y)~7MQ>aBMjA6e2*Qzy;t z^yo7%hodwx{9yI`FxCZ_drn9}IDGQDoxE?;+Tf9c;gjr4icU13e6Rjy*N zilD7WD((yVaU88mKc~dOgEgZv_zJqLjsvTOvno%8%pxsR-cFo!~AY3$P~4hIW#1z^O*DX>q+DUkTwWpD6DoaPlKaSM_vgPdi- zG%Nb{$}gyp+U7Gk5)=ASaH7D%j9b@~y`>%sy?JSszxE$OI=QVR>(c91iIi?_4NaGAM@D#NBaBwpM;L_~h{{TED(8d2aR(b#AHd3060mKBOmHuA| z=wX50|ux(h8F%47ubyAM(edelDRDgFhZfTk!-ncmEgH+(XXG*@ukKuq1dp zQ(Lt!sQ^pQM4#`iv_sAwXL`0_fi87Xk5u>t<#kJms#9_j#+#SJ#V*7_$_?u+Ao03e3Tk=^#ucv8wm1z4ot9#O39FKsW?NHG2=9E6%erkGT?NnWug-` zD5&2t=!8<;4v*T64=^eo$FAK(d5tW7gE+Q`(Ivh1g9eZY7fD=mW5nmi=d{t2b7MN2 zWsnUEazb$HGm8@S032~y?5Pp5vL>(0vbuRhA334;o>8xM2UG6Si}g48tY2Pf_lV*~ zA6#h6fvBu!ZapvZ#xp21{nLX%0x@_cPuMI+?RP5oo_+9U8Xg0i>CG$O-JIA;3NMk# z3iAKl_cqC>#&kytY(DQ~l0|+Q_zEWmWcL=2BvUNB_CT?^l-A}jaQ^WVaLyFT!^5oo#gTS&Y0a%tJfiSfhe-ZI+eTGuPS}@Y4a7dmcDV7 z|52lE#lk^N);vD#SHG%a;{%--FZ zRQpAEUOXExXxG3uKE}oMj?c`fzOuVK)Y46lZxh1i>#%D(FXnvcA97-?i z{HvM%smdQ!R`Gq!AiEI5LkO7E>5Xm7_aTdiBYeZ`k%UK!H?_>sLqb`EgBnlD2OWCF zPyHu9Wt6Rxg+~S!Pa5AOqkj?0E%G}L%AXwmEV8Q7OfK`XKeTQcsv?^8%Xp`9ZBo<} z=P96CL98aihkdTc84;KC1{@iD7(Aj<<$_|w0A7&qOUA8$Xd(FTv@G6^r6N{_8J8y;y~}+1kN4lp-U;7ZSB&3C`$1Kr7c(OnB!nQ;Ajc07 zd&jfL)V*C`e_FZ2^QKJr=3HmL8>N2Uhm9whZ@2(wD#p5_t}fx+$P(LwtYW$m#GjXU zA9NlY9%>wzxs@FLG_jI3OAZfSU`#5iQb`t&YVp=uYov!{9B%wdR(Zs0uZWn;>BITH z@$bI6qv9OL>NO4f1LM78^X}KHT3nWd=f~2Jo!&A$0TVa?xP2nW6f5-Ovc!1lVU(t` zNy&MW;#1H4cUv{xaKjls9j-=sKQTDYO9YfKp@bVl*ban;#}O74d>lI(PanLG+_W;I zDm0qMpPuC}!rgn*Oij0&kSB40!q*-f%W324nPx5ZCf}IN1Y(%u30nbko-0hjDZ7)* ztUEW-eu<2ZW~YlRg-R>F)i+FI#t+ThotJ1vm$H>w6fM_2VQ#eb#e$x9Z)okyr7*uq zhefsz9PYUZ!Q8{VwF{eCb&G7{FJ1X3J{sjM*&3s1ve z8b?j}HI`+~h%k69afAGiA9RvcoDokNSH;Qr+{05T$0{xpWm3wFqqsdKHzCQ0-f^Y$2wD9sP(^Ydfyz89bee;Q3uBk~2wWR7)w#YL33{1u${ixyBBzs6C8`A0R zIQSqTP&|b>(RF#;rwXN^8%r`cl>`@)GI2^30_ zmd~u2#iX?zGD{aH;K~!kiI<>gFY1GH4@UEs$eXL@)DwTFC@4Y-X&54p-8rO z&AkQ}5-yReR5Yj1n?+xgT<5CrllD-)ualW}Nct8(?b75PAAp;h?7ak%adK1iz!G-e z8Ee>bjV7sR*^f251=7HyKUHI2y+P0~FVbt0nHeA07E*6N*{`b&uo4pN)i)#3Rbq)D zL)8Xik7zQt&mpL+5cvvq`v+GHc;^zxCvn`~wk>(;9&Chi`Q~}`@%o0AEJ!Sd(9qJL z2RdUa7S3zNan!i!uH|AOXMnDKWa#$!)E!Q|4LO4s@`s@Q;-Xv!PoLRMeZO%L1Y(9{ zb~Y2d=WJb^dg%sn)lnx}+MeqO^e$Ff#08|OB1!YA1JWfMEW#Xa8q z=j)`2;FHY0VqJBUV{#SSs1v zu-s&avQ^h|(%Rb>pO`asm^H8f!!#6I0#ghMX_kK&Yqh{?;m7R|+9eIfUaR56s!z^{ z4SL1>Uqt7scrP~olIL0#$isPi#1AN8wqCttgR!Z%#Jj<)n^qVy2wXUsLvhhD{1xJUHJkpPTLtC*lpGgSASbHg;y%)W6K8ZVz`y$GR1E5 z@U)%beVuh{ZTOUmbWwpyPegnpXT`WCp5|a$P1ytBD?v^r*Uxd^I+)U!7Xw1|_|ej1Csp48Yny(M`q$35qT z*OK{+H|SZ6o{mZH0O`v{TCWTSXg`Q}pFzi);~MSU3=zZAENw#^ZSZ?}h5o6uG>WypZK$r})wZI$nV)sHQ=dRG{TSJ0{CV$iL@kN4d4{xC z?Atj;znKFkc3#%N-*!}e6Mlt8%b|U1!&}i=$;H2$)cu1#?ewXSf@cJUPuasQ%&XcqI?8> zlsi*7c*>|^@4TaTR=^8kQDR!R zUHdpWZyoUY8Tngyl0sfdy2Rj`_g7587;C<-3Q}gAA&|z!5ibVQ-IcPwnptVW%t1dB zT&v>gfb?P++}QYj{8U;3MZ~hT3(H(hOtB|I0&La?u75oRdS#P^>(HfyJW8|c=$1?k zQByK!F|*I(qh;kWnoPA@vcK&4YrptmklluQg{mPY3<7{#M0_@bXnp2R&My^k>R2_u zFaDh^vN@zzi?5E}HOqUJ(>cG|peT}$nCy-GS#P$kffuz`448(i_ia?|QX&hgWAJ+; zXDd1lQB`GU7{zA%LckzK!_Hgkj~j<)f27sIYAHe68*@WV{IG*O&619B5YPyBiIFMwT7Lg26nq0PapvDD z=Q3nkOLd%Le|B^%``f(<}|U>Dww*>;YDD{q%2c^Pk4gpg%M)6Zv^)XEF?&n!M@CveHur7B zWF9W-5*cdYU8|E)rITdT>bq1)|JnGXP(Rc*8|g%ivLA2~xLTdo+Fy#^t*Grr%7`8Y zSRC5>k%xFkGSDvla)=6d*r!46TS3S{$T#%N=E2lSi&-t!;C)xnAt?{hQz`N)*5FNA%@+f5yi^3c@h_<_5xzYa)t>}p6r8GZ)^PZ%%D!;^I}sj1iuGFx%u zj{~`1Ssa9!+y^pGg5XJ(R?ZQK!&;_PztkZ01u^&W!azIxfh=ld1x+=@)VBX-gPce8 zgCiubue5nIW|QvYJQb(MkcsJxWEq79*zXVwUqwW5D5D?e?73k4O3{noe1_m_ zLoh+jHa8u~ZW>lj!;mcb*L0wdN=^}+E%=Hb%_l7=r`_bxU^UdZX9e?U*@*{czfe8e_R*(L%vt}pYz zW9~z{d@z~3e`oLwOEuau#vTF zwJM08jL@lP4bqx^si(Rwe%V{{C>e7E*I?c1ZjQHVX+c`98l_d;Sf6~nBPnUTIk-Vb!u*0h z05#zD-je%eBgl=r*yb(M@o*NMN#k0~6=86^7b3wN)}f=*A`vgp2V&$nqad8;HMJk1 z8OH(=Hx43l`ZRsgpIlONH|hCgkYk78t@wUf*HE#ufNRA1Q4Eh2@8EyBVBneW*&j-T!P<}^tiw@jPm5*DEt_Ev0-P+OGDu@`U`D3fK(9=`<9Q+ zytQAO)v8`}s@nm#$0IbS82EClHqGQpBd6#)V;Cu|x{oq2tpz_E=fenW#;N*@onm*6 z7OkHP8HoE%H)D4R>jtV?Edk^Y`=8Nj32!}ffQ<7*O%f1V_h~*~`hOV1vfntEk2JVw z<1m$2Ld2POT0SQ-*MKbh-+9eL?VR`9kD5XcYMjPln$9!hOI@H$gpSGoxp?^RON%;z z+h5$l=RhlURUC~@TN{lFT^xcQ)w*Lq)UI#K8o(YiHS8M|s>U&2&+>iP^91;6=->fj zw~~`sB#5oGxe2W=5?x9<$f#;`q4RR%SYKwo91Uz#s3qwvpHMj%6`&fY*s2b%Be!Rw z&*%j#2v#FJ-Ws7BWJCL`l@Xabw+3XFr^(8)o?o>1Vnn$Xx~e!i-xNVf+~Bj;^@WA( z6+z_huws&d{_T$5*V;@?cL~eOgW7?VaSbv5g&7t-EsMln&xcLH2d}+(WV3Vf^rV75 z-$~>?)QKS%dyb-xKb03Ir6CToOoa0P;@jmZFCZy_4|DPnk3A|a3+YVgNzMM_5cukOfw$B!FJJ@A>{<-oq((6il98t-qgU|2dL285<#0`zxJ8Y>e& zi8;e&E|2S5l?!FZqKLKMX7CXCfY^3fzfd!!c9H7k)NeTBM0?r6w-tlUFzd?9DjMsr zD>LWxz=<&iWS9BgF`gpP?9umS=GZcN1D6c^ooW-^7l?|Io@Wylt|3oq@)H)wWU)Ut z#1^GLK}Vefp24i%SABFC033(Y0Fipo^*32QZ&2)kg==BYN`Y(PM%Br*-<@G~Ii39+Za1lB@L0Y&6(}^Bx9sF`9$F=nMkGqEU@1yt}yYTs4UF)oAX|g!JBPrfualUC^ ztAN}0g3YzcWkqjvyFAs;y_6+_bHR$@iDzh8fKdFw`-futPKv0ZuwM34Dexpj!7OiE zUcrG)ik#Z6^s1^m$UkI<11~Et^_+8?Sg}hPIy%fdg}U*Dze5skmlsw6<8tnJ{ialqLfBzb#}0D7+>!T5Ic@!l&3J zTK8g_W{gRKB^fu7et?{9vSu;zsD_rmDaw~i^6)bjUecz+f2A!oLi_E27&SZjwXgZ) zfW&?G40L+)6>D;erHYF7T?he6IUq#n7ZdxrJZ>%97$oQ{~&ZF6G;m7a5| zIv1ix>@6}Ji#5Ejp$+&zXV?Ikp{+gnLmj}muS;nUM^j%E@2BCuJ3GfNn{yjV@=wMI zJh$%!1Q#PC5d2@AkcP@9jcJ#(9B|GM6LYu{T0O>cs;5?=-}~6xr+wz$1N&W*)3nXm zJA=v?kHM1;n1qx0p)WXTCZX6FdSV@qJS}cM_6%9Rflr&!Cm^@Vls#=nCQz*lzp>>q zscBmsNcW&uo}CWOlL!nKfHjOVowt~HJpRT%I-pzdzv@K!*WQ%B-+8ob^%LW@8RZic z4MuP>-It+|(epC(6%$V+&A-Q;zOO7Wdk~58{%dlhz%Fum z%A5bN5VKZ}cLqt*)znI)=6BdV(B$sHjN52_!}Az@V!6=Fy?=jdY44HwpM}_jrJn*( zqJiV`sv5zt=?^w{aRA-N00-f}Y$E+3Cv; zNt?LTi|Kmz10Fg5&;JKR`!b#4ITt^sd`tmipwy~mHygPYC5W{+euOPUW~F9jJ;v8M z9b7~|%X0lzZ(>#dBBJ*@=lB>_!%%YBTOjXYcR6c#4S`E>Mrx2ffT;kUH- zv&-*;gENMXCI^(8Q3*tr4;$C8O2ikOmr7*4+3K+~z-i%`7I`DgW?YnIunD zU2%f$^K(kZ8+64c)XA>;gV&p9!`$Be++U=Np~RG2B3HidE9uIOe0S&l^2!ALZKYpO zc7_SBzS6=S=CBHFnOWKJqo=7JE>dEJiU6`X5MH-7W~>sZ=D0Ht0JYloZn(Nvw^4As zfw?7r$t};i$np(}JI6Wi#7&QgLDN#veB!l{{1SXFuA$nCbG7h=?rQ(N?!aiIT;$Zt^Nj-Csy| zY32HQYd<|7SMI>pzo z&@=S0uL}90YH@QY{0#1T{HnjTBhUlRKIRX;!^-DaelD%TH9U99WhxpF32W-CQuJrB zCfs;enF7J#gn08SdNbD$3WN*sPj4)~CE;2e=RCWZq>|j|IFaE-I1W@i)m3NZ9gwNFE!j z*S0q@FBfWFK0E1fDSWd_qSqNx*cJGp3kfcE!bMJvxdLX+Ae%(Tu7|$!!DRjO7BHE1oO}DOHF?fFVh?v`K7|_p%Q-Te8eQwwc92xLR zmM>_oSbi+6wgK0VAYoc2Cd<{5Twb+DsnLP%e7o=O+18d67bi@Ht5W({Q#teKzz^_8~4p^E`&FKS-=$}dbzo-s1&4VtNVn`8Y zittd*_|{*@2B079i0;2@gZ%Hn=YM;@V?vgtyLek~vAC#ws6cRslg}t=^`pnYSjx!g zv?Ykq3;2G=z-mFE~&_ zo5qO=KW(LuX|iZyY$qf|k2euJq~(45TTb;|%vw^XPPwQhX`<7Lq*s3~MiRM~VLH<51mI*)%1}wcj!d8GMix zTR*-%&WX$ODK8TnZS5UtO;)@_D2Heb@1_Z+mjJ4%X-Fty_DjV>P()hkK+1u7LKI8)n%&+LF6B||pF@Wyr;0Y} zk-eqAN=K!t7Nj;#+%U-aE}4RFkU~HuO)!W&n`9jClqr4=^8>a-CioMqYCPpKzUF8P zH*Sag^jS+nrIXL%$5x$2^3-*E8N?oaSsm)j{GL_((l^^0xFpXApLs**>q=@tnFyc?Hs!H3FuozSQFU#SqSB7@ zJ_s9hYV`|}nL8$Gz*C6!pZglr##8pl3CET)o7}8HA{*`%hc)UgZFTA;ScL#Zz69>! zasuxlrm#O4^J3{ZVAk``%^VJaU`1D4Xu00a&<>_7gD;K%K%eCq9c?T34FX0)zevZ=wUh+09!K1^Q#>61M6$kHQaT z%+kw3-z5;QJ~CV#g8yYU1Oh+s=g+&VI+4-nM@FFvwi^2S(sCZw5=JKwasl)q8K&K1$bC zx`Yjiajd-(2Qie?&6u3M8Wx&yrJ(6Ot$(L7abLKo~igWz3b<^vu_~depFmG

d{z2ghwSm-mLz1XxlZAlF|8 z^#6%VS#6YRsk69SJrH(PKB(?77ssMkVJz5TlhITVCLk%dWKXBnNFV3 z_NOEL>B6C))`Q`;)e5Ov=GmNs&T@KSy_~7{U9K`9WLW)~qXuf)lLxfeS- zuX_1M9Z2(ZkK25npyyI>(~opbbk?aFe9@>Y?Sw8mD4rXT4M;Z0O3#kGWrp46mbN~f z>f+DH?elKK{f`x8;Pjp46tr>rc24>9^=xe&?XyAAe`u!Cyq3OwOj#))UEBt4n9vdb zeCgGE7}G4^g8Zkp-T#RZ@js#-z|`ktQsjIqGSKZYPpyuz=3rXT;s0$1%YVUU0B3Vno-!9voWKK5EuMg45x=I=_qptMnwEw<>T z3(&*>Y|qMBX%84q%j<5@suv67`2G$gAaQA5Jtay2;w`eF*F1yF+V3(rakrdV8UzhF z`~xY;%uPMH?u!dE#@>3x#kGf_TCj6%ZqMbRjdgGrZ@n}4H9yYjl-*83zn5)G>5{t9 z{AB)b)y0P>x9RvGOD8t;4N~Kl*JBuESTr1g0?gu7fZ4bZAa!NBF)lBvU#|dChwaN! zgoeJ%J8A8$IH&H76PD!*SLA44!Gx4n9|MKIL!jAYK<;ueP$=MWn&LjEo?TysGg{i`)2au?3-gE^U6KdfOINVdF0C;J;S=<=aF7zD?htIMAEWjl}^b=mUHm;EJL@|809F zsi|##IpHKcWpDxcKiG<@o`F9EiTCHy&l(C4z4sj z2i^CP28>ppS!*@W3~43j|Ua^s;%ob178-c%_P(S4c$%pgXsFF))#&++i$WsIf-hlT+{K! z%s?KI;XL!<;|#@ASvpsY)S zwbsvCAiPU>KeVIaqas0vZ-)@^Rc8(2?U@?u508yzGtce}8u)E2>j(I@)X{Wi0iCW6 z!3}k;(?w%xRKLcxrKeNdUv{QajE6GJ2MsYNqvz9X<5-ly@`P(}2j3R!sTlI|2l6y7 z6)N%cQ1~0QRmOFS6vs)&^f9kbN!gIP)qmA~_Ud27^ZTy_A>$?9Btxh>7U+wI507EB z8;bRsAQraB^{JXodVH8Yrcr%}g}4ZPp{jlektdyPu{&)HEu$BRl(88;hut)3 zqUVLlh0}wVQlMgu3%3VuFh_aN!;=rEn{tBNZ?3K;uFX!gwE?xNSIr*_T#^DU4pQdp zqW5~{Y?rjlW{SZf!4HsVN00DSwnY8?avY}$g1;$vLm!vBOmfl4Z`D~`EEb>VwI$sS zP+(Eh1x%c4r{_JKT!>dk8i8AM?EQ~>5*w>+VuBC*nZRu99|53v$A%dk8N^M=++#7H zHphIAXVg6q7N`-6Kd-jDx@`hM)xEF}jWrty_bFxkyu9#<^-eXcE0L^5lq@HVw8(o} zs7J!Be*#{^{ZsqpX2585J%ri4sDy*x&JZxm}T zrWQY{yP0q)cin%fIYdIg?%g<#scDT~Vw&-4{%e�eCp;G}@S~S?~0#8RFN@Yr=8v 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 P_{L^pWMNpQ@ABjyq*vRV literal 0 HcmV?d00001 diff --git a/website/docs/assets/site_sync_sftp_settings_local.png b/website/docs/assets/site_sync_sftp_settings_local.png new file mode 100644 index 0000000000000000000000000000000000000000..45125da1a820673400b4368fa5bca2709a4d0247 GIT binary patch literal 7415 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 YO1-W3v*=EN4FQ15m+UNR%zbbE8)?L-;Q#;t literal 0 HcmV?d00001 diff --git a/website/docs/assets/site_sync_sftp_system.png b/website/docs/assets/site_sync_sftp_system.png new file mode 100644 index 0000000000000000000000000000000000000000..6e8e125f9578165e44a37f4f5d88563865576155 GIT binary patch literal 13112 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 HgM|DK Date: Fri, 1 Oct 2021 18:56:30 +0200 Subject: [PATCH 8/8] Fix - updated authentication via ssh key --- .../modules/default_modules/sync_server/providers/sftp.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/modules/default_modules/sync_server/providers/sftp.py b/openpype/modules/default_modules/sync_server/providers/sftp.py index c7a6e9a6203..ce63d35c8c6 100644 --- a/openpype/modules/default_modules/sync_server/providers/sftp.py +++ b/openpype/modules/default_modules/sync_server/providers/sftp.py @@ -4,6 +4,7 @@ import sys import six import threading +import platform from openpype.api import Logger from openpype.api import get_system_settings @@ -406,8 +407,9 @@ def _get_conn(self): } if self.sftp_pass and self.sftp_pass.strip(): conn_params['password'] = self.sftp_pass - if self.sftp_key: - conn_params['private_key'] = self.sftp_key + if self.sftp_key: # expects .pem format, not .ppk! + conn_params['private_key'] = \ + self.sftp_key[platform.system().lower()] if self.sftp_key_pass: conn_params['private_key_pass'] = self.sftp_key_pass