diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 982ba2e..0000000 --- a/.flake8 +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) 2017 Shotgun Software Inc. -# -# CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit -# Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights -# not expressly granted therein are reserved by Shotgun Software Inc. - -# Flake 8 PEP and lint configuration - https://gitlab.com/pycqa/flake8 -# -# This defines the official lint and PEP8 rules for this repository -# -# You can run this locally by doing pep install flake8 and then -# >flake8 /path/to/core -# -# This is also used by the hound CI - see the .hound.yml config file. -# -# -[flake8] - -# things we don't want to lint -exclude = - .tox, - .git, - .flake8, - .gitignore, - .travis.yml, - .cache, - .eggs, - *.rst, - *.yml, - *.pyc, - *.pyo, - *.egg-info, - __pycache__, - # Those are our third parties, do not lint them! - python/tank_vendor, - com.sg.basic.ps/*, - cep/node_modules/*, - # Otherwise you'll have a lot of 'xxx' imported but unused - python/tank/__init__.py, - python/tank/*/__init__.py, - # Skip the auto-generated ui file. - python/tank/authentication/ui/login_dialog.py, - python/tank/authentication/ui/resources_rc.py, - python/tank/authentication/sso_saml2/*, - tests/python - -# toolkit exceptions -# -# E501 line too long (112 > 79 characters) -# W291 trailing whitespace -# W293 blank line contains whitespace -# W391 blank line at end of file -# E221 multiple spaces before operator -# E261 two whitespaces before end of line comment. -# E402 module level import not top of file -# N802 Variables should be lower case. (clashes with Qt naming conventions) -# N806 Variables should be lower case. (clashes with Qt naming conventions) -# E999 SyntaxError: invalid syntax (hack for hound CI which runs python 3.x) - -ignore = E501, W291, W293, W391, E221, E261, E402, N802, N806, E999 - - diff --git a/README.md b/README.md index 6e56b55..58cfb6f 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,13 @@ -# tk-framework-adobe +[![Reference Documentation](http://img.shields.io/badge/doc-reference-blue.svg)](http://developer.shotgunsoftware.com/tk-framework-adobe) +[![Linting](https://img.shields.io/badge/PEP8%20by-Hound%20CI-a873d1.svg)](https://houndci.com) -A framework for Adobe engines - - -## Development - -### How to set up your development environment - -- To setup the development environment for this project, you will need to obtain the [**ZXPSignCmd**](https://labs.adobe.com/downloads/extensionbuilder3.html) tool provided by Adobe. -- Once you have logged in using your existing Adobe user account, download the **CC Extensions Signing Toolkit**, which will provide you with the necessary executable. -- If you are developing on a **Mac**, please set all necessary variables in `dev/env.mk`. -- If you are developing on **Windows**, please set all necessary variables in `dev\env.cmd` - - -### To install the CEP extension for testing without signing: - -``` -cd path/to/tk-adobe-framework -cd dev -make test -``` - -### To sign the CEP extension - -``` -cd path/to/tk-adobe-framework -cd dev -make sign -``` - - -### To create a certificate for use when signing the CEP extension - -``` -cd path/to/tk-adobe-framework -cd dev -make create_certificate -``` - -**Note:** In the case where the configured `CERTIFICATE_FILE` does not exist, the create_certificate command will be automatically run as part of the _sign_ target. - - -### To remove the latest signed zxp file - -``` -cd path/to/tk-adobe-framework -cd dev -make clean -``` - -### Notes on editing the env files (`env.mk` and `env.cmd`) - -Changes to the env files (`env.mk` and `env.cmd`) will typically not be tracked in git. The information contained in these files is specific to a particular development environment, so tracking changes to that data in git is undesirable. - -If you need to make changes to these files, you can use the following commands: - -``` -git update-index --no-skip-worktree dev/env.mk dev/env.cmd -git add dev\env.* -git commit -m "your message" -git update-index --skip-worktree dev/env.mk dev/env.cmd -``` - -Please be aware that these files contain potentially-sensitive information, such as a certificate password. When making changes to these files and pushing them to a git repository, be sure that you've removed any data that might be considered confidential. +## Documentation +This repository is a part of the Shotgun Pipeline Toolkit. +- For more information about this app and for release notes, *see the wiki section*. +- For API Reference, see http://developer.shotgunsoftware.com/tk-framework-adobe +- For general information and documentation, click here: https://support.shotgunsoftware.com/entries/95441257 +- For information about Shotgun in general, click here: http://www.shotgunsoftware.com/toolkit +## Have a Question? +Don't hesitate to contact us! You can find us on support@shotgunsoftware.com diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 0000000..26cc996 --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,62 @@ +.. _development: + +Framework Development +========================== + +This section covers how to make changes to as well as how to deploy the Adobe framework. + +Setting up your dev environment +------------------------------- + +To setup the development environment for this project, you will need to obtain the +`ZXPSignCmd `_ tool provided +by Adobe. Once you have logged in using your existing Adobe user account, +download the **CC Extensions Signing Toolkit**, which will provide you with the necessary executables. + +- If you are developing on a *Mac* please set all necessary variables in `dev/env.mk`. +- On *Windows* please fill all necessary variables in `dev\env.cmd` + + +Building and signing the extension +---------------------------------- + +Once set up, you can test and sign with the following targets: + +.. note:: + Be sure to run all of the following commands from the top-level directory of this project. + +- To install the CEP extension for testing without signing: + + .. code-block:: shell + + cd dev + make test + +- To sign the CEP extension: + + .. code-block:: shell + + cd dev + make sign + +- To create a certificate for use when signing the CEP extension: + + .. code-block:: shell + + cd dev + make create_certificate + + .. note:: + In the case where the configured ``CERTIFICATE_FILE`` does not exist, the ``create_certificate`` + command will be automatically run as part of the process. + + +- To remove the latest signed zxp file: + + .. code-block:: shell + + cd dev + make clean + + + diff --git a/docs/engine_development.rst b/docs/engine_development.rst new file mode 100644 index 0000000..85cef23 --- /dev/null +++ b/docs/engine_development.rst @@ -0,0 +1,71 @@ +Developing Adobe Engines +======================== + +This section explains you can use the Adobe Framework when writing an Adobe engine. + +In your engine, load and initialize the framework:: + + # import the framework module + adobe_bridge = sgtk.platform.import_framework( + "tk-framework-adobe", + "tk_framework_adobe.adobe_bridge" + ) + AdobeBridge = adobe_bridge.AdobeBridge + + # get the adobe instance. it may have been initialized already by a + # previous instance of the engine. if not, initialize a new one. + adobe = AdobeBridge.get_or_create( + identifier='tk-myengine', + logger=self.logger, # engine logger + ) + + # connect to all the adobe bridge signals + adobe.logging_received.connect(self._handle_logging) + adobe.command_received.connect(self._handle_command) + adobe.active_document_changed.connect(self._handle_active_document_change) + adobe.run_tests_request_received.connect(self._run_tests) + adobe.state_requested.connect(self.__send_state) + + # Adobe API will be accessible via the adobe object + temp_thumb_file = adobe.File('/tmp/foo.jpeg') + save_for_web = adobe.ExportType.SAVEFORWEB + export_options = adobe.ExportOptionsSaveForWeb() + adobe.app.activeDocument.exportDocument(temp_thumb_file, save_for_web, export_options) + + +The API exposed via the ``adobe`` bridge will depend on the Application that the framework is connecting to. +The above example shows Photoshop - in this case, the API is +defined `here `_. + + +Adobe Communicator +------------------ + +This is the main object that the Framework exposes. It is responsible for bringing +the entire global Adobe API javascript scope recursively into python. Once an instance +of the AdobeBridge class has been created, this instance can be +used as entry point to javascript-objects inside the Adobe host. +The instance will always return ProxyWrapper objects, that represent javascript objects or functions. + +.. autoclass:: python.tk_framework_adobe.adobe_bridge.AdobeBridge + :inherited-members: + :members: + :exclude-members: save_as, save_as_psb + + +Exceptions +---------- + +.. autoclass:: python.tk_framework_adobe.adobe_bridge.RPCTimeoutError + + +Utilities +--------- + +In order to simplify the engine installation logic in the startup.py of the engine, the following method is provided. + +.. automodule:: python.tk_framework_adobe_utils.startup + :members: ensure_extension_up_to_date + + + diff --git a/docs/index.rst b/docs/index.rst index c8bc6dd..1d47d4b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,6 +3,15 @@ The Shotgun Adobe Framework The Shotgun Adobe Framework contains a common integration platform for Adobe Products, unifying and simplifying the process of writing a Shotgun Toolkit integration for an -Application that is part of the Adobe Suite. +Application that is part of the Adobe Suite. On the following pages you will get +more information about this framework and its specialities. + +Contents: + +.. toctree:: + :maxdepth: 2 + + overview + development + engine_development -More documentation coming soon. diff --git a/docs/overview.rst b/docs/overview.rst new file mode 100644 index 0000000..736cf47 --- /dev/null +++ b/docs/overview.rst @@ -0,0 +1,112 @@ +Framework Overview +=================================== + +This framework provides a platform for integrating Shotgun into +the Adobe product ecosystem. Examples of how it is currently being +used include the `Photoshop Engine `_ +as well as the `After Effects Engine `_. +The central technical component is an an Adobe CC extension built upon Adobe's +`Common Extensibility Platform `_ (CEP). + +This framework handles the following: + +- Automatic installation and updates of the adobe extension at runtime. +- Automatic wrapping of adobe API methods so that they are accessible in Toolkit and Python. +- A standardized adobe panel which shows Toolkit icons and allows a user to launch Toolkit apps. + + +CEP extension +------------- + +The CEP extension is installed on the artist's local machine in the standard, OS-specific CEP +extension directories:: + + # Windows + > C:\Users\[user name]\AppData\Roaming\Adobe\CEP\extensions\ + + # OS X + > ~/Library/Application Support/Adobe/CEP/extensions/ + + +Each time an Adobe engine is launched, the engine bootstrap code will check the +version of the extension that is bundled with the engine against the version +that is installed on the machine. This means that after an engine update, +assuming a new version of the extension came with it, the installed extension +will be automatically updated to the newly-bundled version. + + +To understand the CEP technology that the extension is based on, the following +resources can be useful: + +- The `CEP HTML Extension Cookbook `_, describing how to develop CEP panels. + +- The `CEP-Samples `_ collection. + +.. note:: + Before deployment, the CEP extension needs to be signed. This process + is described in the :ref:`development` section. + + +Application specific logic +-------------------------- + +As the framework provides a single, signed adobe extension that is meant +to be shared between all Adobe applications, it was was not possible +to completely avoid application specific values inside of it. +When implementing a new engine for a new adobe product, the following files have to +be modified: + +- ``cep/CSXS/manifest.xml`` - Add your host and supported minimum version number here:: + + + ... + + + ... + + + Replace SHORTCODE with the CEP-name of your Host Application (``AEFT`` for After effects), + and ``12.3`` with your minimum supported internal version of the Host Application. + For example ``14.0`` is equivalent to After Effects 2017. + +- ``cep/.debug`` - Similar to the manifest above, please add your new host to + the debug lists and define a unique custom port. + +- ``cep/js/shotgun/constants.js`` - Add a new section describing your host as follows:: + + sg_constants.product_info = { + ... + // Your Host + SHORTCODE: { + display_name: "Your Host Nice Name", + tk_engine_name: "tk-your-engine-name", + debug_url: "http://localhost:PORTNUM" + } + ... + } + + Please replace PORTNUM with the unique port used in ``cep/.debug``. + +Environment Variables +--------------------- + +To aid in debugging, there are a set of environment variables that change some +of the framework's default values: + +- ``SHOTGUN_ADOBE_DISABLE_AUTO_INSTALL`` - Prevents the startup process from + attempting to automatically install or update the extension bundled with the engine. + +- ``SHOTGUN_ADOBE_HEARTBEAT_TIMEOUT`` - How long, in seconds, Python waits for + Photoshop to answer its heartbeat (default is 0.5 seconds). + +- ``SHOTGUN_ADOBE_NETWORK_DEBUG`` - Include additional networking debug messages + when logging output. + +- ``SHOTGUN_ADOBE_PYTHON`` - The path to the Python executable to use when launching the + engine. If not set, the system Python is used. If the Adobe DCC is launched from a Python + process, like Shotgun Desktop or via the tk-shell engine, the Python used by that + process will be used by the integration. + +- ``SHOTGUN_ADOBE_RESPONSE_TIMEOUT`` - How long, in seconds, Python waits for a + response from the DCC (default is 300 seconds). + diff --git a/framework.py b/framework.py index 07a8c9c..27f3b6c 100644 --- a/framework.py +++ b/framework.py @@ -1,10 +1,20 @@ -""" -Adobe CC Framework -""" +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + import sgtk class AdobeFramework(sgtk.platform.Framework): + """ + Adobe CC Framework + """ ########################################################################################## # init and destroy diff --git a/python/__init__.py b/python/__init__.py index d282d78..cc8654f 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -1,3 +1,13 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + import sys try: diff --git a/python/tk_framework_adobe/__init__.py b/python/tk_framework_adobe/__init__.py index 596340f..724d3b9 100644 --- a/python/tk_framework_adobe/__init__.py +++ b/python/tk_framework_adobe/__init__.py @@ -10,3 +10,6 @@ from .classic_init import toolkit_classic_bootstrap from .plugin_init import toolkit_plugin_bootstrap + +from .adobe_bridge import Communicator +from .errors import RPCTimeoutError diff --git a/python/tk_framework_adobe/adobe_bridge.py b/python/tk_framework_adobe/adobe_bridge.py index 8123ffc..9f05e6e 100644 --- a/python/tk_framework_adobe/adobe_bridge.py +++ b/python/tk_framework_adobe/adobe_bridge.py @@ -7,78 +7,13 @@ # By accessing, using, copying or modifying this work you indicate your # agreement to the Shotgun Pipeline Toolkit Source Code License. All rights # not expressly granted therein are reserved by Shotgun Software Inc. -import os -import functools -import threading - - -from sgtk.platform.qt import QtCore - +import os import json - -from rpc import Communicator - - -########################################################################################## -# functions - - -def timeout(seconds=5.0, error_message="Timed out."): - """ - A timeout decorator. When the given amount of time has passed - after the decorated callable is called, if it has not completed - an RPCTimeoutError is raised. - - :param float seconds: The timeout duration, in seconds. - :param str error_message: The error message to raise once timed out. - """ - def decorator(func): - def _handle_timeout(): - raise RPCTimeoutError(error_message) - - def wrapper(*args, **kwargs): - timer = threading.Timer(float(seconds), _handle_timeout) - try: - timer.start() - result = func(*args, **kwargs) - finally: - timer.cancel() - return result - - return functools.wraps(func)(wrapper) - return decorator - - -########################################################################################## -# classes - - -class MessageEmitter(QtCore.QObject): - """ - Container QObject for Qt signals fired when messages requesting certain - actions take place in Python arrive from the remote process. - - :signal logging_received(str, str): Fires when a logging call has been - received. The first string is the logging level (debug, info, warning, - or error) and the second string is the message. - :signal command_received(int): Fires when an engine command has been - received. The integer value is the unique id of the engine command - that was requested to be executed. - :signal run_tests_request_received: Fires when a request for unit tests to - be run has been received. - :signal state_requested: Fires when the remote process requests the current - state. - :signal active_document_changed(str): Fires when alerted to a change in active - document by the RPC server. The string value is the path to the new - active document, or an empty string if the active document is unsaved. - """ - logging_received = QtCore.Signal(str, str) - command_received = QtCore.Signal(int) - run_tests_request_received = QtCore.Signal() - state_requested = QtCore.Signal() - active_document_changed = QtCore.Signal(str) +from .rpc import Communicator +from .utils import timeout, MessageEmitter +from .errors import RPCTimeoutError class AdobeBridge(Communicator): @@ -172,6 +107,8 @@ def ping(self): """ Pings the socket.io server to test whether the connection is still active. + + :raises: :class:`RPCTimeoutError` """ super(AdobeBridge, self).ping() @@ -418,18 +355,8 @@ def _wait_for_response(self, uid): :param int uid: The unique id of the RPC call to wait for. :returns: The raw returned results data. + :raises: :class:`RPCTimeoutError` """ return super(AdobeBridge, self)._wait_for_response(uid) -########################################################################################## -# exceptions - - -class RPCTimeoutError(Exception): - """ - Raised when an RPC event times out. - """ - pass - - diff --git a/python/tk_framework_adobe/errors.py b/python/tk_framework_adobe/errors.py new file mode 100644 index 0000000..dd0a633 --- /dev/null +++ b/python/tk_framework_adobe/errors.py @@ -0,0 +1,16 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + + +class RPCTimeoutError(Exception): + """ + Raised when an RPC event times out. + """ + pass diff --git a/python/tk_framework_adobe/log.py b/python/tk_framework_adobe/log.py index d64cb6a..fbe6e67 100644 --- a/python/tk_framework_adobe/log.py +++ b/python/tk_framework_adobe/log.py @@ -7,6 +7,7 @@ # By accessing, using, copying or modifying this work you indicate your # agreement to the Shotgun Pipeline Toolkit Source Code License. All rights # not expressly granted therein are reserved by Shotgun Software Inc. + import os import logging @@ -56,11 +57,10 @@ def get_sgtk_logger(sgtk): # the log should go to a file named like the engine, which is to be started # if the engine is unknown to the current environment, it will just log # into the frameworks own log-file - log_name = os.getenv('SHOTGUN_ENGINE', 'tk-framework-adobe') + log_name = os.getenv("SHOTGUN_ENGINE", "tk-framework-adobe") # initializes the file where logging output will go sgtk.LogManager().initialize_base_file_handler(log_name) return bootstrap_log_handler - diff --git a/python/tk_framework_adobe/plugin_init.py b/python/tk_framework_adobe/plugin_init.py index 53ddf65..cbcf9d0 100644 --- a/python/tk_framework_adobe/plugin_init.py +++ b/python/tk_framework_adobe/plugin_init.py @@ -7,6 +7,7 @@ # By accessing, using, copying or modifying this work you indicate your # agreement to the Shotgun Pipeline Toolkit Source Code License. All rights # not expressly granted therein are reserved by Shotgun Software Inc. + import sys import os import log diff --git a/python/tk_framework_adobe/utils.py b/python/tk_framework_adobe/utils.py new file mode 100644 index 0000000..7b5e97a --- /dev/null +++ b/python/tk_framework_adobe/utils.py @@ -0,0 +1,70 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + +import functools +import threading + +from sgtk.platform.qt import QtCore +from .errors import RPCTimeoutError + + +def timeout(seconds=5.0, error_message="Timed out."): + """ + A timeout decorator. When the given amount of time has passed + after the decorated callable is called, if it has not completed + an RPCTimeoutError is raised. + + :param float seconds: The timeout duration, in seconds. + :param str error_message: The error message to raise once timed out. + """ + def decorator(func): + def _handle_timeout(): + raise RPCTimeoutError(error_message) + + def wrapper(*args, **kwargs): + timer = threading.Timer(float(seconds), _handle_timeout) + try: + timer.start() + result = func(*args, **kwargs) + finally: + timer.cancel() + return result + + return functools.wraps(func)(wrapper) + return decorator + + + +class MessageEmitter(QtCore.QObject): + """ + Container QObject for Qt signals fired when messages requesting certain + actions take place in Python arrive from the remote process. + + :signal logging_received(str, str): Fires when a logging call has been + received. The first string is the logging level (debug, info, warning, + or error) and the second string is the message. + :signal command_received(int): Fires when an engine command has been + received. The integer value is the unique id of the engine command + that was requested to be executed. + :signal run_tests_request_received: Fires when a request for unit tests to + be run has been received. + :signal state_requested: Fires when the remote process requests the current + state. + :signal active_document_changed(str): Fires when alerted to a change in active + document by the RPC server. The string value is the path to the new + active document, or an empty string if the active document is unsaved. + """ + logging_received = QtCore.Signal(str, str) + command_received = QtCore.Signal(int) + run_tests_request_received = QtCore.Signal() + state_requested = QtCore.Signal() + active_document_changed = QtCore.Signal(str) + + diff --git a/python/tk_framework_adobe_utils/__init__.py b/python/tk_framework_adobe_utils/__init__.py index e69de29..4c2afad 100644 --- a/python/tk_framework_adobe_utils/__init__.py +++ b/python/tk_framework_adobe_utils/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. diff --git a/python/tk_framework_adobe_utils/environment_utils.py b/python/tk_framework_adobe_utils/environment_utils.py index 5915aca..2a94964 100644 --- a/python/tk_framework_adobe_utils/environment_utils.py +++ b/python/tk_framework_adobe_utils/environment_utils.py @@ -1,3 +1,13 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + import os import sys diff --git a/python/tk_framework_adobe_utils/plugin_bootstrap.py b/python/tk_framework_adobe_utils/plugin_bootstrap.py index 66df43b..7426863 100644 --- a/python/tk_framework_adobe_utils/plugin_bootstrap.py +++ b/python/tk_framework_adobe_utils/plugin_bootstrap.py @@ -7,6 +7,7 @@ # By accessing, using, copying or modifying this work you indicate your # agreement to the Shotgun Pipeline Toolkit Source Code License. All rights # not expressly granted therein are reserved by Shotgun Software Inc. + import sys sys.dont_write_bytecode = True diff --git a/python/tk_framework_adobe_utils/startup.py b/python/tk_framework_adobe_utils/startup.py index 4aa68f4..42c5794 100644 --- a/python/tk_framework_adobe_utils/startup.py +++ b/python/tk_framework_adobe_utils/startup.py @@ -1,3 +1,13 @@ +# Copyright (c) 2019 Shotgun Software Inc. +# +# CONFIDENTIAL AND PROPRIETARY +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# Source Code License included in this distribution package. See LICENSE. +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# not expressly granted therein are reserved by Shotgun Software Inc. + """ Utilities for installing the CEP extension in case this is out of date """ diff --git a/python/tk_framework_adobe_utils/win_32_api.py b/python/tk_framework_adobe_utils/win_32_api.py index 5ebe2f2..5d075cd 100644 --- a/python/tk_framework_adobe_utils/win_32_api.py +++ b/python/tk_framework_adobe_utils/win_32_api.py @@ -1,11 +1,11 @@ # Copyright (c) 2019 Shotgun Software Inc. -# +# # CONFIDENTIAL AND PROPRIETARY -# -# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit +# +# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit # Source Code License included in this distribution package. See LICENSE. -# By accessing, using, copying or modifying this work you indicate your -# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights +# By accessing, using, copying or modifying this work you indicate your +# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights # not expressly granted therein are reserved by Shotgun Software Inc. """ @@ -32,7 +32,7 @@ SetForegroundWindow = ctypes.windll.user32.SetForegroundWindow ############################################################################ -# kernal32.dll +# kernel32.dll CloseHandle = ctypes.windll.kernel32.CloseHandle CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot @@ -84,7 +84,7 @@ def find_parent_process_id(process_id): try: h_process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) - + pe = PROCESSENTRY32() pe.dwSize = ctypes.sizeof(PROCESSENTRY32) ret = Process32First(h_process_snapshot, ctypes.byref(pe)) @@ -132,7 +132,7 @@ def safe_get_window_text(hwnd): pass return title - + def find_windows(process_id=None, class_name=None, window_text=None, stop_if_found=True): """ @@ -152,12 +152,12 @@ def enum_windows_proc(hwnd, lparam): # try to match process id: matches_proc_id = True if process_id is not None: - win_process_id = ctypes.c_long() + win_process_id = ctypes.c_long() GetWindowThreadProcessId(hwnd, ctypes.byref(win_process_id)) matches_proc_id = (win_process_id.value == process_id) if not matches_proc_id: return True - + # try to match class name: matches_class_name = True if class_name is not None: @@ -167,7 +167,7 @@ def enum_windows_proc(hwnd, lparam): matches_class_name = (class_name == unicode_buffer.value) if not matches_class_name: return True - + # try to match window text: matches_window_text = True if window_text is not None: @@ -175,15 +175,15 @@ def enum_windows_proc(hwnd, lparam): matches_window_text = (window_text in hwnd_text) if not matches_window_text: return True - - # found a match + + # found a match found_hwnds.append(hwnd) - + return not stop_if_found - + # enumerate all top-level windows: EnumWindows(EnumWindowsProc(enum_windows_proc), None) - + return found_hwnds @@ -198,10 +198,10 @@ def qwidget_winid_to_hwnd(winid): # Setup arguments and return types. ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object] - + # Convert PyCObject to a void pointer. hwnd = ctypes.pythonapi.PyCObject_AsVoidPtr(winid) - + return hwnd def bring_to_front(hwnd):