mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
211 lines
6.6 KiB
Python
211 lines
6.6 KiB
Python
import os
|
|
import json
|
|
import tempfile
|
|
import random
|
|
import string
|
|
|
|
from Qt import QtWidgets, QtCore
|
|
|
|
from openpype.api import execute, Logger
|
|
from openpype.pipeline import legacy_io
|
|
from openpype.lib import (
|
|
get_openpype_execute_args,
|
|
apply_project_environments_value
|
|
)
|
|
|
|
from . import DropDataFrame
|
|
from .constants import HOST_NAME
|
|
|
|
log = Logger.get_logger("standalonepublisher")
|
|
|
|
|
|
class ComponentsWidget(QtWidgets.QWidget):
|
|
def __init__(self, parent):
|
|
super().__init__()
|
|
self.initialized = False
|
|
self.valid_components = False
|
|
self.valid_family = False
|
|
self.valid_repre_names = False
|
|
|
|
body = QtWidgets.QWidget()
|
|
self.parent_widget = parent
|
|
self.drop_frame = DropDataFrame(self)
|
|
|
|
buttons = QtWidgets.QWidget()
|
|
|
|
layout = QtWidgets.QHBoxLayout(buttons)
|
|
|
|
self.btn_browse = QtWidgets.QPushButton('Browse')
|
|
self.btn_browse.setToolTip('Browse for file(s).')
|
|
self.btn_browse.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
self.btn_publish = QtWidgets.QPushButton('Publish')
|
|
self.btn_publish.setToolTip('Publishes data.')
|
|
self.btn_publish.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
layout.addWidget(self.btn_browse, alignment=QtCore.Qt.AlignLeft)
|
|
layout.addWidget(self.btn_publish, alignment=QtCore.Qt.AlignRight)
|
|
|
|
layout = QtWidgets.QVBoxLayout(body)
|
|
layout.setSpacing(0)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
layout.addWidget(self.drop_frame)
|
|
layout.addWidget(buttons)
|
|
|
|
layout = QtWidgets.QVBoxLayout(self)
|
|
layout.setSpacing(0)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
layout.addWidget(body)
|
|
|
|
self.btn_browse.clicked.connect(self._browse)
|
|
self.btn_publish.clicked.connect(self._publish)
|
|
self.initialized = True
|
|
|
|
def validation(self):
|
|
if self.initialized is False:
|
|
return
|
|
valid = (
|
|
self.parent_widget.valid_family and
|
|
self.valid_components and
|
|
self.valid_repre_names
|
|
)
|
|
self.btn_publish.setEnabled(valid)
|
|
|
|
def set_valid_components(self, valid):
|
|
self.valid_components = valid
|
|
self.validation()
|
|
|
|
def set_valid_repre_names(self, valid):
|
|
self.valid_repre_names = valid
|
|
self.validation()
|
|
|
|
def process_mime_data(self, mime_data):
|
|
self.drop_frame.process_ent_mime(mime_data)
|
|
|
|
def collect_data(self):
|
|
return self.drop_frame.collect_data()
|
|
|
|
def _browse(self):
|
|
options = [
|
|
QtWidgets.QFileDialog.DontResolveSymlinks,
|
|
QtWidgets.QFileDialog.DontUseNativeDialog
|
|
]
|
|
folders = False
|
|
if folders:
|
|
# browse folders specifics
|
|
caption = "Browse folders to publish image sequences"
|
|
file_mode = QtWidgets.QFileDialog.Directory
|
|
options.append(QtWidgets.QFileDialog.ShowDirsOnly)
|
|
else:
|
|
# browse files specifics
|
|
caption = "Browse files to publish"
|
|
file_mode = QtWidgets.QFileDialog.ExistingFiles
|
|
|
|
# create the dialog
|
|
file_dialog = QtWidgets.QFileDialog(parent=self, caption=caption)
|
|
file_dialog.setLabelText(QtWidgets.QFileDialog.Accept, "Select")
|
|
file_dialog.setLabelText(QtWidgets.QFileDialog.Reject, "Cancel")
|
|
file_dialog.setFileMode(file_mode)
|
|
|
|
# set the appropriate options
|
|
for option in options:
|
|
file_dialog.setOption(option)
|
|
|
|
# browse!
|
|
if not file_dialog.exec_():
|
|
return
|
|
|
|
# process the browsed files/folders for publishing
|
|
paths = file_dialog.selectedFiles()
|
|
self.drop_frame._process_paths(paths)
|
|
|
|
def working_start(self, msg=None):
|
|
if hasattr(self, 'parent_widget'):
|
|
self.parent_widget.working_start(msg)
|
|
|
|
def working_stop(self):
|
|
if hasattr(self, 'parent_widget'):
|
|
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()
|
|
set_context(
|
|
data['project'],
|
|
data['asset'],
|
|
data['task']
|
|
)
|
|
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
|
|
legacy_io.Session["AVALON_PROJECT"] = project
|
|
os.environ["AVALON_ASSET"] = asset
|
|
legacy_io.Session["AVALON_ASSET"] = asset
|
|
if not task:
|
|
task = ''
|
|
os.environ["AVALON_TASK"] = task
|
|
legacy_io.Session["AVALON_TASK"] = task
|
|
|
|
legacy_io.Session["current_dir"] = os.path.normpath(os.getcwd())
|
|
|
|
os.environ["AVALON_APP"] = HOST_NAME
|
|
legacy_io.Session["AVALON_APP"] = HOST_NAME
|
|
|
|
|
|
def cli_publish(data, publish_paths, gui=True):
|
|
PUBLISH_SCRIPT_PATH = os.path.join(
|
|
os.path.dirname(os.path.dirname(__file__)),
|
|
"publish.py"
|
|
)
|
|
legacy_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"
|
|
|
|
project_name = os.environ["AVALON_PROJECT"]
|
|
env_copy = apply_project_environments_value(project_name, envcopy)
|
|
|
|
args = get_openpype_execute_args("run", PUBLISH_SCRIPT_PATH)
|
|
result = execute(args, env=envcopy)
|
|
|
|
result = {}
|
|
if os.path.exists(json_data_path):
|
|
with open(json_data_path, "r") as f:
|
|
result = json.load(f)
|
|
os.remove(json_data_path)
|
|
|
|
log.info(f"Publish result: {result}")
|
|
|
|
legacy_io.uninstall()
|
|
|
|
return False
|