diff --git a/pype/modules/standalonepublish/__init__.py b/pype/modules/standalonepublish/__init__.py index 8e615afbea..4038b696d9 100644 --- a/pype/modules/standalonepublish/__init__.py +++ b/pype/modules/standalonepublish/__init__.py @@ -1,14 +1,5 @@ -PUBLISH_PATHS = [] - from .standalonepublish_module import StandAlonePublishModule -from .app import ( - show, - cli -) -__all__ = [ - "show", - "cli" -] + def tray_init(tray_widget, main_widget): return StandAlonePublishModule(main_widget, tray_widget) diff --git a/pype/modules/standalonepublish/__main__.py b/pype/modules/standalonepublish/__main__.py deleted file mode 100644 index d77bc585c5..0000000000 --- a/pype/modules/standalonepublish/__main__.py +++ /dev/null @@ -1,5 +0,0 @@ -from . import cli - -if __name__ == '__main__': - import sys - sys.exit(cli(sys.argv[1:])) diff --git a/pype/modules/standalonepublish/publish.py b/pype/modules/standalonepublish/publish.py deleted file mode 100644 index 27062e8457..0000000000 --- a/pype/modules/standalonepublish/publish.py +++ /dev/null @@ -1,133 +0,0 @@ -import os -import sys -import json -import tempfile -import random -import string - -from avalon import io -import pype -from pype.api import execute, Logger - -import pyblish.api - - -log = Logger().get_logger("standalonepublisher") - - -def set_context(project, asset, task, app): - ''' Sets context for pyblish (must be done before pyblish is launched) - :param project: Name of `Project` where instance should be published - :type project: str - :param asset: Name of `Asset` where instance should be published - :type asset: str - ''' - os.environ["AVALON_PROJECT"] = project - io.Session["AVALON_PROJECT"] = project - os.environ["AVALON_ASSET"] = asset - io.Session["AVALON_ASSET"] = asset - if not task: - task = '' - os.environ["AVALON_TASK"] = task - io.Session["AVALON_TASK"] = task - - io.install() - - av_project = io.find_one({'type': 'project'}) - av_asset = io.find_one({ - "type": 'asset', - "name": asset - }) - - parents = av_asset['data']['parents'] - hierarchy = '' - if parents and len(parents) > 0: - hierarchy = os.path.sep.join(parents) - - os.environ["AVALON_HIERARCHY"] = hierarchy - io.Session["AVALON_HIERARCHY"] = hierarchy - - os.environ["AVALON_PROJECTCODE"] = av_project['data'].get('code', '') - io.Session["AVALON_PROJECTCODE"] = av_project['data'].get('code', '') - - io.Session["current_dir"] = os.path.normpath(os.getcwd()) - - os.environ["AVALON_APP"] = app - io.Session["AVALON_APP"] = app - - io.uninstall() - - -def publish(data, gui=True): - # cli pyblish seems like better solution - return cli_publish(data, gui) - - -def cli_publish(data, gui=True): - from . import PUBLISH_PATHS - - PUBLISH_SCRIPT_PATH = os.path.join(os.path.dirname(__file__), "publish.py") - io.install() - - # Create hash name folder in temp - chars = "".join([random.choice(string.ascii_letters) for i in range(15)]) - staging_dir = tempfile.mkdtemp(chars) - - # create also json and fill with data - json_data_path = staging_dir + os.path.basename(staging_dir) + '.json' - with open(json_data_path, 'w') as outfile: - json.dump(data, outfile) - - envcopy = os.environ.copy() - envcopy["PYBLISH_HOSTS"] = "standalonepublisher" - envcopy["SAPUBLISH_INPATH"] = json_data_path - envcopy["PYBLISHGUI"] = "pyblish_pype" - envcopy["PUBLISH_PATHS"] = os.pathsep.join(PUBLISH_PATHS) - if data.get("family", "").lower() == "editorial": - envcopy["PYBLISH_SUSPEND_LOGS"] = "1" - - result = execute( - [sys.executable, PUBLISH_SCRIPT_PATH], - env=envcopy - ) - - result = {} - if os.path.exists(json_data_path): - with open(json_data_path, "r") as f: - result = json.load(f) - - log.info(f"Publish result: {result}") - - io.uninstall() - - return False - - -def main(env): - from avalon.tools import publish - # Registers pype's Global pyblish plugins - pype.install() - - # Register additional paths - addition_paths_str = env.get("PUBLISH_PATHS") or "" - addition_paths = addition_paths_str.split(os.pathsep) - for path in addition_paths: - path = os.path.normpath(path) - if not os.path.exists(path): - continue - pyblish.api.register_plugin_path(path) - - # Register project specific plugins - project_name = os.environ["AVALON_PROJECT"] - project_plugins_paths = env.get("PYPE_PROJECT_PLUGINS") or "" - for path in project_plugins_paths.split(os.pathsep): - plugin_path = os.path.join(path, project_name, "plugins") - if os.path.exists(plugin_path): - pyblish.api.register_plugin_path(plugin_path) - - return publish.show() - - -if __name__ == "__main__": - result = main(os.environ) - sys.exit(not bool(result)) diff --git a/pype/modules/standalonepublish/standalonepublish_module.py b/pype/modules/standalonepublish/standalonepublish_module.py index 64195bc271..ed997bfd9f 100644 --- a/pype/modules/standalonepublish/standalonepublish_module.py +++ b/pype/modules/standalonepublish/standalonepublish_module.py @@ -1,21 +1,22 @@ import os -from .app import show -from .widgets import QtWidgets +import sys +import subprocess import pype -from . import PUBLISH_PATHS +from pype import tools class StandAlonePublishModule: - def __init__(self, main_parent=None, parent=None): self.main_parent = main_parent self.parent_widget = parent - PUBLISH_PATHS.clear() - PUBLISH_PATHS.append(os.path.sep.join( - [pype.PLUGINS_DIR, "standalonepublisher", "publish"] - )) + self.publish_paths = [ + os.path.join( + pype.PLUGINS_DIR, "standalonepublisher", "publish" + ) + ] def tray_menu(self, parent_menu): + from Qt import QtWidgets self.run_action = QtWidgets.QAction( "Publish", parent_menu ) @@ -24,9 +25,17 @@ class StandAlonePublishModule: def process_modules(self, modules): if "FtrackModule" in modules: - PUBLISH_PATHS.append(os.path.sep.join( - [pype.PLUGINS_DIR, "ftrack", "publish"] + self.publish_paths.append(os.path.join( + pype.PLUGINS_DIR, "ftrack", "publish" )) def show(self): - show(self.main_parent, False) + standalone_publisher_tool_path = os.path.join( + os.path.dirname(tools.__file__), + "standalonepublish" + ) + subprocess.Popen([ + sys.executable, + standalone_publisher_tool_path, + os.pathsep.join(self.publish_paths).replace("\\", "/") + ]) diff --git a/pype/modules/standalonepublish/widgets/button_from_svgs.py b/pype/modules/standalonepublish/widgets/button_from_svgs.py deleted file mode 100644 index 4255c5f29b..0000000000 --- a/pype/modules/standalonepublish/widgets/button_from_svgs.py +++ /dev/null @@ -1,113 +0,0 @@ -from xml.dom import minidom - -from . import QtGui, QtCore, QtWidgets -from PyQt5 import QtSvg, QtXml - - -class SvgResizable(QtSvg.QSvgWidget): - clicked = QtCore.Signal() - - def __init__(self, filepath, width=None, height=None, fill=None): - super().__init__() - self.xmldoc = minidom.parse(filepath) - itemlist = self.xmldoc.getElementsByTagName('svg') - for element in itemlist: - if fill: - element.setAttribute('fill', str(fill)) - # TODO auto scale if only one is set - if width is not None and height is not None: - self.setMaximumSize(width, height) - self.setMinimumSize(width, height) - xml_string = self.xmldoc.toxml() - svg_bytes = bytearray(xml_string, encoding='utf-8') - - self.load(svg_bytes) - - def change_color(self, color): - element = self.xmldoc.getElementsByTagName('svg')[0] - element.setAttribute('fill', str(color)) - xml_string = self.xmldoc.toxml() - svg_bytes = bytearray(xml_string, encoding='utf-8') - self.load(svg_bytes) - - def mousePressEvent(self, event): - self.clicked.emit() - - -class SvgButton(QtWidgets.QFrame): - clicked = QtCore.Signal() - def __init__( - self, filepath, width=None, height=None, fills=[], - parent=None, checkable=True - ): - super().__init__(parent) - self.checkable = checkable - self.checked = False - - xmldoc = minidom.parse(filepath) - element = xmldoc.getElementsByTagName('svg')[0] - c_actual = '#777777' - if element.hasAttribute('fill'): - c_actual = element.getAttribute('fill') - self.store_fills(fills, c_actual) - - self.installEventFilter(self) - self.svg_widget = SvgResizable(filepath, width, height, self.c_normal) - xmldoc = minidom.parse(filepath) - - layout = QtWidgets.QHBoxLayout(self) - layout.setSpacing(0) - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(self.svg_widget) - - if width is not None and height is not None: - self.setMaximumSize(width, height) - self.setMinimumSize(width, height) - - def store_fills(self, fills, actual): - if len(fills) == 0: - fills = [actual, actual, actual, actual] - elif len(fills) == 1: - fills = [fills[0], fills[0], fills[0], fills[0]] - elif len(fills) == 2: - fills = [fills[0], fills[1], fills[1], fills[1]] - elif len(fills) == 3: - fills = [fills[0], fills[1], fills[2], fills[2]] - self.c_normal = fills[0] - self.c_hover = fills[1] - self.c_active = fills[2] - self.c_active_hover = fills[3] - - def eventFilter(self, object, event): - if event.type() == QtCore.QEvent.Enter: - self.hoverEnterEvent(event) - return True - elif event.type() == QtCore.QEvent.Leave: - self.hoverLeaveEvent(event) - return True - elif event.type() == QtCore.QEvent.MouseButtonRelease: - self.mousePressEvent(event) - return False - - def change_checked(self, hover=True): - if self.checkable: - self.checked = not self.checked - if hover: - self.hoverEnterEvent() - else: - self.hoverLeaveEvent() - - def hoverEnterEvent(self, event=None): - color = self.c_hover - if self.checked: - color = self.c_active_hover - self.svg_widget.change_color(color) - - def hoverLeaveEvent(self, event=None): - color = self.c_normal - if self.checked: - color = self.c_active - self.svg_widget.change_color(color) - - def mousePressEvent(self, event=None): - self.clicked.emit() diff --git a/pype/tools/standalonepublish/__init__.py b/pype/tools/standalonepublish/__init__.py new file mode 100644 index 0000000000..29a4e52904 --- /dev/null +++ b/pype/tools/standalonepublish/__init__.py @@ -0,0 +1,8 @@ +from .app import ( + show, + cli +) +__all__ = [ + "show", + "cli" +] diff --git a/pype/tools/standalonepublish/__main__.py b/pype/tools/standalonepublish/__main__.py new file mode 100644 index 0000000000..aba8e6c0a4 --- /dev/null +++ b/pype/tools/standalonepublish/__main__.py @@ -0,0 +1,24 @@ +import os +import sys +import app +import signal +from Qt import QtWidgets +from avalon import style + + +if __name__ == "__main__": + qt_app = QtWidgets.QApplication([]) + # app.setQuitOnLastWindowClosed(False) + qt_app.setStyleSheet(style.load_stylesheet()) + + def signal_handler(sig, frame): + print("You pressed Ctrl+C. Process ended.") + qt_app.quit() + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + window = app.Window(sys.argv[-1].split(os.pathsep)) + window.show() + + sys.exit(qt_app.exec_()) diff --git a/pype/modules/standalonepublish/app.py b/pype/tools/standalonepublish/app.py similarity index 82% rename from pype/modules/standalonepublish/app.py rename to pype/tools/standalonepublish/app.py index 60274f6b0a..d139366a1c 100644 --- a/pype/modules/standalonepublish/app.py +++ b/pype/tools/standalonepublish/app.py @@ -1,18 +1,8 @@ -import os -import sys -import json -from subprocess import Popen from bson.objectid import ObjectId -from pype import lib as pypelib -from avalon.vendor.Qt import QtWidgets, QtCore -from avalon import api, style, schema -from avalon.tools import lib as parentlib -from .widgets import * -# Move this to pype lib? +from Qt import QtWidgets, QtCore +from widgets import AssetWidget, FamilyWidget, ComponentsWidget, ShadowWidget from avalon.tools.libraryloader.io_nonsingleton import DbConnector -module = sys.modules[__name__] -module.window = None class Window(QtWidgets.QDialog): """Main window of Standalone publisher. @@ -28,14 +18,15 @@ class Window(QtWidgets.QDialog): WIDTH = 1100 HEIGHT = 500 - def __init__(self, parent=None): + def __init__(self, pyblish_paths, parent=None): super(Window, self).__init__(parent=parent) self._db.install() + self.pyblish_paths = pyblish_paths + self.setWindowTitle("Standalone Publish") self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.setStyleSheet(style.load_stylesheet()) # Validators self.valid_parent = False @@ -99,8 +90,14 @@ class Window(QtWidgets.QDialog): def resizeEvent(self, event=None): ''' Helps resize shadow widget ''' - position_x = (self.frameGeometry().width()-self.shadow_widget.frameGeometry().width())/2 - position_y = (self.frameGeometry().height()-self.shadow_widget.frameGeometry().height())/2 + position_x = ( + self.frameGeometry().width() + - self.shadow_widget.frameGeometry().width() + ) / 2 + position_y = ( + self.frameGeometry().height() + - self.shadow_widget.frameGeometry().height() + ) / 2 self.shadow_widget.move(position_x, position_y) w = self.frameGeometry().width() h = self.frameGeometry().height() @@ -144,7 +141,10 @@ class Window(QtWidgets.QDialog): - files/folders in clipboard (tested only on Windows OS) - copied path of file/folder in clipboard ('c:/path/to/folder') ''' - if event.key() == QtCore.Qt.Key_V and event.modifiers() == QtCore.Qt.ControlModifier: + if ( + event.key() == QtCore.Qt.Key_V + and event.modifiers() == QtCore.Qt.ControlModifier + ): clip = QtWidgets.QApplication.clipboard() self.widget_components.process_mime_data(clip) super().keyPressEvent(event) @@ -190,29 +190,3 @@ class Window(QtWidgets.QDialog): data.update(self.widget_components.collect_data()) return data - -def show(parent=None, debug=False): - try: - module.window.close() - del module.window - except (RuntimeError, AttributeError): - pass - - with parentlib.application(): - window = Window(parent) - window.show() - - module.window = window - - -def cli(args): - import argparse - parser = argparse.ArgumentParser() - parser.add_argument("project") - parser.add_argument("asset") - - args = parser.parse_args(args) - # project = args.project - # asset = args.asset - - show() diff --git a/pype/tools/standalonepublish/publish.py b/pype/tools/standalonepublish/publish.py new file mode 100644 index 0000000000..a4bb81ad3c --- /dev/null +++ b/pype/tools/standalonepublish/publish.py @@ -0,0 +1,35 @@ +import os +import sys + +import pype +import pyblish.api + + +def main(env): + from avalon.tools import publish + # Registers pype's Global pyblish plugins + pype.install() + + # Register additional paths + addition_paths_str = env.get("PUBLISH_PATHS") or "" + addition_paths = addition_paths_str.split(os.pathsep) + for path in addition_paths: + path = os.path.normpath(path) + if not os.path.exists(path): + continue + pyblish.api.register_plugin_path(path) + + # Register project specific plugins + project_name = os.environ["AVALON_PROJECT"] + project_plugins_paths = env.get("PYPE_PROJECT_PLUGINS") or "" + for path in project_plugins_paths.split(os.pathsep): + plugin_path = os.path.join(path, project_name, "plugins") + if os.path.exists(plugin_path): + pyblish.api.register_plugin_path(plugin_path) + + return publish.show() + + +if __name__ == "__main__": + result = main(os.environ) + sys.exit(not bool(result)) diff --git a/pype/modules/standalonepublish/resources/__init__.py b/pype/tools/standalonepublish/resources/__init__.py similarity index 100% rename from pype/modules/standalonepublish/resources/__init__.py rename to pype/tools/standalonepublish/resources/__init__.py diff --git a/pype/modules/standalonepublish/resources/edit.svg b/pype/tools/standalonepublish/resources/edit.svg similarity index 100% rename from pype/modules/standalonepublish/resources/edit.svg rename to pype/tools/standalonepublish/resources/edit.svg diff --git a/pype/modules/standalonepublish/resources/file.png b/pype/tools/standalonepublish/resources/file.png similarity index 100% rename from pype/modules/standalonepublish/resources/file.png rename to pype/tools/standalonepublish/resources/file.png diff --git a/pype/modules/standalonepublish/resources/files.png b/pype/tools/standalonepublish/resources/files.png similarity index 100% rename from pype/modules/standalonepublish/resources/files.png rename to pype/tools/standalonepublish/resources/files.png diff --git a/pype/modules/standalonepublish/resources/houdini.png b/pype/tools/standalonepublish/resources/houdini.png similarity index 100% rename from pype/modules/standalonepublish/resources/houdini.png rename to pype/tools/standalonepublish/resources/houdini.png diff --git a/pype/modules/standalonepublish/resources/image_file.png b/pype/tools/standalonepublish/resources/image_file.png similarity index 100% rename from pype/modules/standalonepublish/resources/image_file.png rename to pype/tools/standalonepublish/resources/image_file.png diff --git a/pype/modules/standalonepublish/resources/image_files.png b/pype/tools/standalonepublish/resources/image_files.png similarity index 100% rename from pype/modules/standalonepublish/resources/image_files.png rename to pype/tools/standalonepublish/resources/image_files.png diff --git a/pype/modules/standalonepublish/resources/information.svg b/pype/tools/standalonepublish/resources/information.svg similarity index 100% rename from pype/modules/standalonepublish/resources/information.svg rename to pype/tools/standalonepublish/resources/information.svg diff --git a/pype/modules/standalonepublish/resources/maya.png b/pype/tools/standalonepublish/resources/maya.png similarity index 100% rename from pype/modules/standalonepublish/resources/maya.png rename to pype/tools/standalonepublish/resources/maya.png diff --git a/pype/modules/standalonepublish/resources/menu.png b/pype/tools/standalonepublish/resources/menu.png similarity index 100% rename from pype/modules/standalonepublish/resources/menu.png rename to pype/tools/standalonepublish/resources/menu.png diff --git a/pype/modules/standalonepublish/resources/menu_disabled.png b/pype/tools/standalonepublish/resources/menu_disabled.png similarity index 100% rename from pype/modules/standalonepublish/resources/menu_disabled.png rename to pype/tools/standalonepublish/resources/menu_disabled.png diff --git a/pype/modules/standalonepublish/resources/menu_hover.png b/pype/tools/standalonepublish/resources/menu_hover.png similarity index 100% rename from pype/modules/standalonepublish/resources/menu_hover.png rename to pype/tools/standalonepublish/resources/menu_hover.png diff --git a/pype/modules/standalonepublish/resources/menu_pressed.png b/pype/tools/standalonepublish/resources/menu_pressed.png similarity index 100% rename from pype/modules/standalonepublish/resources/menu_pressed.png rename to pype/tools/standalonepublish/resources/menu_pressed.png diff --git a/pype/modules/standalonepublish/resources/menu_pressed_hover.png b/pype/tools/standalonepublish/resources/menu_pressed_hover.png similarity index 100% rename from pype/modules/standalonepublish/resources/menu_pressed_hover.png rename to pype/tools/standalonepublish/resources/menu_pressed_hover.png diff --git a/pype/modules/standalonepublish/resources/nuke.png b/pype/tools/standalonepublish/resources/nuke.png similarity index 100% rename from pype/modules/standalonepublish/resources/nuke.png rename to pype/tools/standalonepublish/resources/nuke.png diff --git a/pype/modules/standalonepublish/resources/premiere.png b/pype/tools/standalonepublish/resources/premiere.png similarity index 100% rename from pype/modules/standalonepublish/resources/premiere.png rename to pype/tools/standalonepublish/resources/premiere.png diff --git a/pype/modules/standalonepublish/resources/trash.png b/pype/tools/standalonepublish/resources/trash.png similarity index 100% rename from pype/modules/standalonepublish/resources/trash.png rename to pype/tools/standalonepublish/resources/trash.png diff --git a/pype/modules/standalonepublish/resources/trash_disabled.png b/pype/tools/standalonepublish/resources/trash_disabled.png similarity index 100% rename from pype/modules/standalonepublish/resources/trash_disabled.png rename to pype/tools/standalonepublish/resources/trash_disabled.png diff --git a/pype/modules/standalonepublish/resources/trash_hover.png b/pype/tools/standalonepublish/resources/trash_hover.png similarity index 100% rename from pype/modules/standalonepublish/resources/trash_hover.png rename to pype/tools/standalonepublish/resources/trash_hover.png diff --git a/pype/modules/standalonepublish/resources/trash_pressed.png b/pype/tools/standalonepublish/resources/trash_pressed.png similarity index 100% rename from pype/modules/standalonepublish/resources/trash_pressed.png rename to pype/tools/standalonepublish/resources/trash_pressed.png diff --git a/pype/modules/standalonepublish/resources/trash_pressed_hover.png b/pype/tools/standalonepublish/resources/trash_pressed_hover.png similarity index 100% rename from pype/modules/standalonepublish/resources/trash_pressed_hover.png rename to pype/tools/standalonepublish/resources/trash_pressed_hover.png diff --git a/pype/modules/standalonepublish/resources/video_file.png b/pype/tools/standalonepublish/resources/video_file.png similarity index 100% rename from pype/modules/standalonepublish/resources/video_file.png rename to pype/tools/standalonepublish/resources/video_file.png diff --git a/pype/modules/standalonepublish/widgets/__init__.py b/pype/tools/standalonepublish/widgets/__init__.py similarity index 84% rename from pype/modules/standalonepublish/widgets/__init__.py rename to pype/tools/standalonepublish/widgets/__init__.py index 9a71e0dee6..e61897f807 100644 --- a/pype/modules/standalonepublish/widgets/__init__.py +++ b/pype/tools/standalonepublish/widgets/__init__.py @@ -1,6 +1,4 @@ -from avalon.vendor.Qt import * -from avalon.vendor import qtawesome -from avalon import style +from Qt import QtCore HelpRole = QtCore.Qt.UserRole + 2 FamilyRole = QtCore.Qt.UserRole + 3 @@ -8,9 +6,6 @@ ExistsRole = QtCore.Qt.UserRole + 4 PluginRole = QtCore.Qt.UserRole + 5 PluginKeyRole = QtCore.Qt.UserRole + 6 -from ..resources import get_resource -from .button_from_svgs import SvgResizable, SvgButton - from .model_node import Node from .model_tree import TreeModel from .model_asset import AssetModel, _iter_model_rows diff --git a/pype/modules/standalonepublish/widgets/model_asset.py b/pype/tools/standalonepublish/widgets/model_asset.py similarity index 98% rename from pype/modules/standalonepublish/widgets/model_asset.py rename to pype/tools/standalonepublish/widgets/model_asset.py index 6bea35ebd7..44649b3dc3 100644 --- a/pype/modules/standalonepublish/widgets/model_asset.py +++ b/pype/tools/standalonepublish/widgets/model_asset.py @@ -1,8 +1,9 @@ import logging import collections -from . import QtCore, QtGui +from Qt import QtCore, QtGui from . import TreeModel, Node -from . import style, qtawesome +from avalon.vendor import qtawesome +from avalon import style log = logging.getLogger(__name__) diff --git a/pype/modules/standalonepublish/widgets/model_filter_proxy_exact_match.py b/pype/tools/standalonepublish/widgets/model_filter_proxy_exact_match.py similarity index 97% rename from pype/modules/standalonepublish/widgets/model_filter_proxy_exact_match.py rename to pype/tools/standalonepublish/widgets/model_filter_proxy_exact_match.py index 862e4071db..604ae30934 100644 --- a/pype/modules/standalonepublish/widgets/model_filter_proxy_exact_match.py +++ b/pype/tools/standalonepublish/widgets/model_filter_proxy_exact_match.py @@ -1,4 +1,4 @@ -from . import QtCore +from Qt import QtCore class ExactMatchesFilterProxyModel(QtCore.QSortFilterProxyModel): diff --git a/pype/modules/standalonepublish/widgets/model_filter_proxy_recursive_sort.py b/pype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py similarity index 97% rename from pype/modules/standalonepublish/widgets/model_filter_proxy_recursive_sort.py rename to pype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py index 9528e96ebf..71ecdf41dc 100644 --- a/pype/modules/standalonepublish/widgets/model_filter_proxy_recursive_sort.py +++ b/pype/tools/standalonepublish/widgets/model_filter_proxy_recursive_sort.py @@ -1,4 +1,4 @@ -from . import QtCore +from Qt import QtCore import re diff --git a/pype/modules/standalonepublish/widgets/model_node.py b/pype/tools/standalonepublish/widgets/model_node.py similarity index 100% rename from pype/modules/standalonepublish/widgets/model_node.py rename to pype/tools/standalonepublish/widgets/model_node.py diff --git a/pype/modules/standalonepublish/widgets/model_tasks_template.py b/pype/tools/standalonepublish/widgets/model_tasks_template.py similarity index 92% rename from pype/modules/standalonepublish/widgets/model_tasks_template.py rename to pype/tools/standalonepublish/widgets/model_tasks_template.py index 336921b37a..476f45391d 100644 --- a/pype/modules/standalonepublish/widgets/model_tasks_template.py +++ b/pype/tools/standalonepublish/widgets/model_tasks_template.py @@ -1,6 +1,7 @@ -from . import QtCore, TreeModel -from . import Node -from . import qtawesome, style +from Qt import QtCore +from . import Node, TreeModel +from avalon.vendor import qtawesome +from avalon import style class TasksTemplateModel(TreeModel): diff --git a/pype/modules/standalonepublish/widgets/model_tree.py b/pype/tools/standalonepublish/widgets/model_tree.py similarity index 99% rename from pype/modules/standalonepublish/widgets/model_tree.py rename to pype/tools/standalonepublish/widgets/model_tree.py index f37b7a00b2..efac0d6b78 100644 --- a/pype/modules/standalonepublish/widgets/model_tree.py +++ b/pype/tools/standalonepublish/widgets/model_tree.py @@ -1,4 +1,4 @@ -from . import QtCore +from Qt import QtCore from . import Node diff --git a/pype/modules/standalonepublish/widgets/model_tree_view_deselectable.py b/pype/tools/standalonepublish/widgets/model_tree_view_deselectable.py similarity index 93% rename from pype/modules/standalonepublish/widgets/model_tree_view_deselectable.py rename to pype/tools/standalonepublish/widgets/model_tree_view_deselectable.py index 78bec44d36..6a15916981 100644 --- a/pype/modules/standalonepublish/widgets/model_tree_view_deselectable.py +++ b/pype/tools/standalonepublish/widgets/model_tree_view_deselectable.py @@ -1,4 +1,4 @@ -from . import QtWidgets, QtCore +from Qt import QtWidgets, QtCore class DeselectableTreeView(QtWidgets.QTreeView): diff --git a/pype/modules/standalonepublish/widgets/widget_asset.py b/pype/tools/standalonepublish/widgets/widget_asset.py similarity index 99% rename from pype/modules/standalonepublish/widgets/widget_asset.py rename to pype/tools/standalonepublish/widgets/widget_asset.py index d9241bd91f..c468c9627b 100644 --- a/pype/modules/standalonepublish/widgets/widget_asset.py +++ b/pype/tools/standalonepublish/widgets/widget_asset.py @@ -1,7 +1,8 @@ import contextlib -from . import QtWidgets, QtCore +from Qt import QtWidgets, QtCore from . import RecursiveSortFilterProxyModel, AssetModel -from . import qtawesome, style +from avalon.vendor import qtawesome +from avalon import style from . import TasksTemplateModel, DeselectableTreeView from . import _iter_model_rows diff --git a/pype/modules/standalonepublish/widgets/widget_component_item.py b/pype/tools/standalonepublish/widgets/widget_component_item.py similarity index 99% rename from pype/modules/standalonepublish/widgets/widget_component_item.py rename to pype/tools/standalonepublish/widgets/widget_component_item.py index 40298520b1..dd838075e3 100644 --- a/pype/modules/standalonepublish/widgets/widget_component_item.py +++ b/pype/tools/standalonepublish/widgets/widget_component_item.py @@ -1,6 +1,6 @@ import os -from . import QtCore, QtGui, QtWidgets -from . import get_resource +from Qt import QtCore, QtGui, QtWidgets +from pype.resources import get_resource from avalon import style diff --git a/pype/modules/standalonepublish/widgets/widget_components.py b/pype/tools/standalonepublish/widgets/widget_components.py similarity index 57% rename from pype/modules/standalonepublish/widgets/widget_components.py rename to pype/tools/standalonepublish/widgets/widget_components.py index 90167f2fa6..7e0327f00a 100644 --- a/pype/modules/standalonepublish/widgets/widget_components.py +++ b/pype/tools/standalonepublish/widgets/widget_components.py @@ -1,7 +1,16 @@ -from . import QtWidgets, QtCore, QtGui -from . import DropDataFrame +import os +import sys +import json +import tempfile +import random +import string -from .. import publish +from Qt import QtWidgets, QtCore +from . import DropDataFrame +from avalon import io +from pype.api import execute, Logger + +log = Logger().get_logger("standalonepublisher") class ComponentsWidget(QtWidgets.QWidget): @@ -113,16 +122,103 @@ class ComponentsWidget(QtWidgets.QWidget): self.parent_widget.working_stop() def _publish(self): + log.info(self.parent_widget.pyblish_paths) self.working_start('Pyblish is running') try: data = self.parent_widget.collect_data() - publish.set_context( - data['project'], data['asset'], data['task'], 'standalonepublish' + set_context( + data['project'], + data['asset'], + data['task'] ) - result = publish.publish(data) + result = cli_publish(data, self.parent_widget.pyblish_paths) # Clear widgets from components list if publishing was successful if result: self.drop_frame.components_list.clear_widgets() self.drop_frame._refresh_view() finally: self.working_stop() + + +def set_context(project, asset, task): + ''' Sets context for pyblish (must be done before pyblish is launched) + :param project: Name of `Project` where instance should be published + :type project: str + :param asset: Name of `Asset` where instance should be published + :type asset: str + ''' + os.environ["AVALON_PROJECT"] = project + io.Session["AVALON_PROJECT"] = project + os.environ["AVALON_ASSET"] = asset + io.Session["AVALON_ASSET"] = asset + if not task: + task = '' + os.environ["AVALON_TASK"] = task + io.Session["AVALON_TASK"] = task + + io.install() + + av_project = io.find_one({'type': 'project'}) + av_asset = io.find_one({ + "type": 'asset', + "name": asset + }) + + parents = av_asset['data']['parents'] + hierarchy = '' + if parents and len(parents) > 0: + hierarchy = os.path.sep.join(parents) + + os.environ["AVALON_HIERARCHY"] = hierarchy + io.Session["AVALON_HIERARCHY"] = hierarchy + + os.environ["AVALON_PROJECTCODE"] = av_project['data'].get('code', '') + io.Session["AVALON_PROJECTCODE"] = av_project['data'].get('code', '') + + io.Session["current_dir"] = os.path.normpath(os.getcwd()) + + os.environ["AVALON_APP"] = "standalonepublish" + io.Session["AVALON_APP"] = "standalonepublish" + + io.uninstall() + + +def cli_publish(data, publish_paths, gui=True): + PUBLISH_SCRIPT_PATH = os.path.join( + os.path.dirname(os.path.dirname(__file__)), + "publish.py" + ) + io.install() + + # Create hash name folder in temp + chars = "".join([random.choice(string.ascii_letters) for i in range(15)]) + staging_dir = tempfile.mkdtemp(chars) + + # create also json and fill with data + json_data_path = staging_dir + os.path.basename(staging_dir) + '.json' + with open(json_data_path, 'w') as outfile: + json.dump(data, outfile) + + envcopy = os.environ.copy() + envcopy["PYBLISH_HOSTS"] = "standalonepublisher" + envcopy["SAPUBLISH_INPATH"] = json_data_path + envcopy["PYBLISHGUI"] = "pyblish_pype" + envcopy["PUBLISH_PATHS"] = os.pathsep.join(publish_paths) + if data.get("family", "").lower() == "editorial": + envcopy["PYBLISH_SUSPEND_LOGS"] = "1" + + result = execute( + [sys.executable, PUBLISH_SCRIPT_PATH], + env=envcopy + ) + + result = {} + if os.path.exists(json_data_path): + with open(json_data_path, "r") as f: + result = json.load(f) + + log.info(f"Publish result: {result}") + + io.uninstall() + + return False diff --git a/pype/modules/standalonepublish/widgets/widget_components_list.py b/pype/tools/standalonepublish/widgets/widget_components_list.py similarity index 98% rename from pype/modules/standalonepublish/widgets/widget_components_list.py rename to pype/tools/standalonepublish/widgets/widget_components_list.py index f85e9f0aa6..4e502a2e5f 100644 --- a/pype/modules/standalonepublish/widgets/widget_components_list.py +++ b/pype/tools/standalonepublish/widgets/widget_components_list.py @@ -1,4 +1,4 @@ -from . import QtCore, QtGui, QtWidgets +from Qt import QtWidgets class ComponentsList(QtWidgets.QTableWidget): diff --git a/pype/modules/standalonepublish/widgets/widget_drop_empty.py b/pype/tools/standalonepublish/widgets/widget_drop_empty.py similarity index 82% rename from pype/modules/standalonepublish/widgets/widget_drop_empty.py rename to pype/tools/standalonepublish/widgets/widget_drop_empty.py index d352e70355..ed526f2a78 100644 --- a/pype/modules/standalonepublish/widgets/widget_drop_empty.py +++ b/pype/tools/standalonepublish/widgets/widget_drop_empty.py @@ -1,7 +1,4 @@ -import os -import logging -import clique -from . import QtWidgets, QtCore, QtGui +from Qt import QtWidgets, QtCore, QtGui class DropEmpty(QtWidgets.QWidget): @@ -42,11 +39,13 @@ class DropEmpty(QtWidgets.QWidget): super().paintEvent(event) painter = QtGui.QPainter(self) pen = QtGui.QPen() - pen.setWidth(1); - pen.setBrush(QtCore.Qt.darkGray); - pen.setStyle(QtCore.Qt.DashLine); + pen.setWidth(1) + pen.setBrush(QtCore.Qt.darkGray) + pen.setStyle(QtCore.Qt.DashLine) painter.setPen(pen) painter.drawRect( - 10, 10, - self.rect().width()-15, self.rect().height()-15 + 10, + 10, + self.rect().width() - 15, + self.rect().height() - 15 ) diff --git a/pype/modules/standalonepublish/widgets/widget_drop_frame.py b/pype/tools/standalonepublish/widgets/widget_drop_frame.py similarity index 99% rename from pype/modules/standalonepublish/widgets/widget_drop_frame.py rename to pype/tools/standalonepublish/widgets/widget_drop_frame.py index 37d22cf887..e13f701b30 100644 --- a/pype/modules/standalonepublish/widgets/widget_drop_frame.py +++ b/pype/tools/standalonepublish/widgets/widget_drop_frame.py @@ -3,9 +3,8 @@ import re import json import clique import subprocess -from pype.api import config import pype.lib -from . import QtWidgets, QtCore +from Qt import QtWidgets, QtCore from . import DropEmpty, ComponentsList, ComponentItem diff --git a/pype/modules/standalonepublish/widgets/widget_family.py b/pype/tools/standalonepublish/widgets/widget_family.py similarity index 99% rename from pype/modules/standalonepublish/widgets/widget_family.py rename to pype/tools/standalonepublish/widgets/widget_family.py index 29a0812a91..1c8f2238fc 100644 --- a/pype/modules/standalonepublish/widgets/widget_family.py +++ b/pype/tools/standalonepublish/widgets/widget_family.py @@ -1,10 +1,6 @@ -import os -import sys -import inspect -import json from collections import namedtuple -from . import QtWidgets, QtCore +from Qt import QtWidgets, QtCore from . import HelpRole, FamilyRole, ExistsRole, PluginRole, PluginKeyRole from . import FamilyDescriptionWidget diff --git a/pype/modules/standalonepublish/widgets/widget_family_desc.py b/pype/tools/standalonepublish/widgets/widget_family_desc.py similarity index 92% rename from pype/modules/standalonepublish/widgets/widget_family_desc.py rename to pype/tools/standalonepublish/widgets/widget_family_desc.py index 7c80dcfd57..8c95ddf2e4 100644 --- a/pype/modules/standalonepublish/widgets/widget_family_desc.py +++ b/pype/tools/standalonepublish/widgets/widget_family_desc.py @@ -1,13 +1,7 @@ -import os -import sys -import inspect -import json - -from . import QtWidgets, QtCore, QtGui -from . import HelpRole, FamilyRole, ExistsRole, PluginRole -from . import qtawesome +from Qt import QtWidgets, QtCore, QtGui +from . import FamilyRole, PluginRole +from avalon.vendor import qtawesome import six -from pype import lib as pypelib class FamilyDescriptionWidget(QtWidgets.QWidget): diff --git a/pype/modules/standalonepublish/widgets/widget_shadow.py b/pype/tools/standalonepublish/widgets/widget_shadow.py similarity index 85% rename from pype/modules/standalonepublish/widgets/widget_shadow.py rename to pype/tools/standalonepublish/widgets/widget_shadow.py index 1bb9cee44b..de5fdf6be0 100644 --- a/pype/modules/standalonepublish/widgets/widget_shadow.py +++ b/pype/tools/standalonepublish/widgets/widget_shadow.py @@ -1,4 +1,4 @@ -from . import QtWidgets, QtCore, QtGui +from Qt import QtWidgets, QtCore, QtGui class ShadowWidget(QtWidgets.QWidget): @@ -26,7 +26,9 @@ class ShadowWidget(QtWidgets.QWidget): painter.begin(self) painter.setFont(self.font) painter.setRenderHint(QtGui.QPainter.Antialiasing) - painter.fillRect(event.rect(), QtGui.QBrush(QtGui.QColor(0, 0, 0, 127))) + painter.fillRect( + event.rect(), QtGui.QBrush(QtGui.QColor(0, 0, 0, 127)) + ) painter.drawText( QtCore.QRectF( 0.0, @@ -34,7 +36,7 @@ class ShadowWidget(QtWidgets.QWidget): self.parent_widget.frameGeometry().width(), self.parent_widget.frameGeometry().height() ), - QtCore.Qt.AlignCenter|QtCore.Qt.AlignCenter, + QtCore.Qt.AlignCenter | QtCore.Qt.AlignCenter, self.message ) painter.end()