Merge branch 'develop' into master-dazzle-prod
|
|
@ -265,6 +265,37 @@ class ProcessEventHub(ftrack_api.event.hub.EventHub):
|
|||
return self._send_packet(self._code_name_mapping["heartbeat"])
|
||||
|
||||
return super()._handle_packet(code, packet_identifier, path, data)
|
||||
|
||||
|
||||
class UserEventHub(ftrack_api.event.hub.EventHub):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.sock = kwargs.pop("sock")
|
||||
super(UserEventHub, self).__init__(*args, **kwargs)
|
||||
|
||||
def _handle_packet(self, code, packet_identifier, path, data):
|
||||
"""Override `_handle_packet` which extend heartbeat"""
|
||||
code_name = self._code_name_mapping[code]
|
||||
if code_name == "heartbeat":
|
||||
# Reply with heartbeat.
|
||||
self.sock.sendall(b"hearbeat")
|
||||
return self._send_packet(self._code_name_mapping['heartbeat'])
|
||||
|
||||
elif code_name == "connect":
|
||||
event = ftrack_api.event.base.Event(
|
||||
topic="pype.storer.started",
|
||||
data={},
|
||||
source={
|
||||
"id": self.id,
|
||||
"user": {"username": self._api_user}
|
||||
}
|
||||
)
|
||||
self._event_queue.put(event)
|
||||
|
||||
return super(UserEventHub, self)._handle_packet(
|
||||
code, packet_identifier, path, data
|
||||
)
|
||||
|
||||
|
||||
class SocketSession(ftrack_api.session.Session):
|
||||
'''An isolated session for interaction with an ftrack server.'''
|
||||
def __init__(
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ class SocketThread(threading.Thread):
|
|||
|
||||
self.mongo_error = False
|
||||
|
||||
self._temp_data = {}
|
||||
|
||||
def stop(self):
|
||||
self._is_running = False
|
||||
|
||||
|
|
@ -81,8 +83,9 @@ class SocketThread(threading.Thread):
|
|||
try:
|
||||
if not self._is_running:
|
||||
break
|
||||
data = None
|
||||
try:
|
||||
data = connection.recv(16)
|
||||
data = self.get_data_from_con(connection)
|
||||
time_con = time.time()
|
||||
|
||||
except socket.timeout:
|
||||
|
|
@ -99,10 +102,7 @@ class SocketThread(threading.Thread):
|
|||
self._is_running = False
|
||||
break
|
||||
|
||||
if data:
|
||||
if data == b"MongoError":
|
||||
self.mongo_error = True
|
||||
connection.sendall(data)
|
||||
self._handle_data(connection, data)
|
||||
|
||||
except Exception as exc:
|
||||
self.log.error(
|
||||
|
|
@ -121,3 +121,14 @@ class SocketThread(threading.Thread):
|
|||
for line in lines:
|
||||
os.write(1, line)
|
||||
self.finished = True
|
||||
|
||||
def get_data_from_con(self, connection):
|
||||
return connection.recv(16)
|
||||
|
||||
def _handle_data(self, connection, data):
|
||||
if not data:
|
||||
return
|
||||
|
||||
if data == b"MongoError":
|
||||
self.mongo_error = True
|
||||
connection.sendall(data)
|
||||
|
|
|
|||
51
pype/ftrack/ftrack_server/sub_user_server.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import sys
|
||||
import signal
|
||||
import socket
|
||||
|
||||
from ftrack_server import FtrackServer
|
||||
from pype.ftrack.ftrack_server.lib import SocketSession, UserEventHub
|
||||
|
||||
from pypeapp import Logger
|
||||
|
||||
log = Logger().get_logger(__name__)
|
||||
|
||||
|
||||
def main(args):
|
||||
port = int(args[-1])
|
||||
|
||||
# Create a TCP/IP socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
# Connect the socket to the port where the server is listening
|
||||
server_address = ("localhost", port)
|
||||
log.debug("Storer connected to {} port {}".format(*server_address))
|
||||
sock.connect(server_address)
|
||||
sock.sendall(b"CreatedUser")
|
||||
|
||||
try:
|
||||
session = SocketSession(
|
||||
auto_connect_event_hub=True, sock=sock, Eventhub=UserEventHub
|
||||
)
|
||||
server = FtrackServer("action")
|
||||
log.debug("Launched Ftrack Event storer")
|
||||
server.run_server(session=session)
|
||||
|
||||
finally:
|
||||
log.debug("Closing socket")
|
||||
sock.close()
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Register interupt signal
|
||||
def signal_handler(sig, frame):
|
||||
log.info(
|
||||
"Process was forced to stop. Process ended."
|
||||
)
|
||||
log.info("Process ended.")
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
sys.exit(main(sys.argv))
|
||||
|
|
@ -1,26 +1,27 @@
|
|||
import os
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
from Qt import QtCore, QtGui, QtWidgets
|
||||
import datetime
|
||||
import threading
|
||||
from Qt import QtCore, QtWidgets
|
||||
|
||||
import ftrack_api
|
||||
from pypeapp import style
|
||||
from pype.ftrack import FtrackServer, check_ftrack_url, credentials
|
||||
from ..ftrack_server.lib import check_ftrack_url
|
||||
from ..ftrack_server import socket_thread
|
||||
from ..lib import credentials
|
||||
from . import login_dialog
|
||||
|
||||
from pype import api as pype
|
||||
from pypeapp import Logger
|
||||
|
||||
|
||||
log = pype.Logger().get_logger("FtrackModule", "ftrack")
|
||||
log = Logger().get_logger("FtrackModule", "ftrack")
|
||||
|
||||
|
||||
class FtrackModule:
|
||||
def __init__(self, main_parent=None, parent=None):
|
||||
self.parent = parent
|
||||
self.widget_login = login_dialog.Login_Dialog_ui(self)
|
||||
self.action_server = FtrackServer('action')
|
||||
self.thread_action_server = None
|
||||
self.thread_socket_server = None
|
||||
self.thread_timer = None
|
||||
|
||||
self.bool_logged = False
|
||||
|
|
@ -75,14 +76,6 @@ class FtrackModule:
|
|||
|
||||
# Actions part
|
||||
def start_action_server(self):
|
||||
self.bool_action_thread_running = True
|
||||
self.set_menu_visibility()
|
||||
if (
|
||||
self.thread_action_server is not None and
|
||||
self.bool_action_thread_running is False
|
||||
):
|
||||
self.stop_action_server()
|
||||
|
||||
if self.thread_action_server is None:
|
||||
self.thread_action_server = threading.Thread(
|
||||
target=self.set_action_server
|
||||
|
|
@ -90,35 +83,114 @@ class FtrackModule:
|
|||
self.thread_action_server.start()
|
||||
|
||||
def set_action_server(self):
|
||||
first_check = True
|
||||
while self.bool_action_thread_running is True:
|
||||
if not check_ftrack_url(os.environ['FTRACK_SERVER']):
|
||||
if first_check:
|
||||
log.warning(
|
||||
"Could not connect to Ftrack server"
|
||||
)
|
||||
first_check = False
|
||||
if self.bool_action_server_running:
|
||||
return
|
||||
|
||||
self.bool_action_server_running = True
|
||||
self.bool_action_thread_running = False
|
||||
|
||||
ftrack_url = os.environ['FTRACK_SERVER']
|
||||
|
||||
parent_file_path = os.path.dirname(
|
||||
os.path.dirname(os.path.realpath(__file__))
|
||||
)
|
||||
|
||||
min_fail_seconds = 5
|
||||
max_fail_count = 3
|
||||
wait_time_after_max_fail = 10
|
||||
|
||||
# Threads data
|
||||
thread_name = "ActionServerThread"
|
||||
thread_port = 10021
|
||||
subprocess_path = (
|
||||
"{}/ftrack_server/sub_user_server.py".format(parent_file_path)
|
||||
)
|
||||
if self.thread_socket_server is not None:
|
||||
self.thread_socket_server.stop()
|
||||
self.thread_socket_server.join()
|
||||
self.thread_socket_server = None
|
||||
|
||||
last_failed = datetime.datetime.now()
|
||||
failed_count = 0
|
||||
|
||||
ftrack_accessible = False
|
||||
printed_ftrack_error = False
|
||||
|
||||
# Main loop
|
||||
while True:
|
||||
if not self.bool_action_server_running:
|
||||
log.debug("Action server was pushed to stop.")
|
||||
break
|
||||
|
||||
# Check if accessible Ftrack and Mongo url
|
||||
if not ftrack_accessible:
|
||||
ftrack_accessible = check_ftrack_url(ftrack_url)
|
||||
|
||||
# Run threads only if Ftrack is accessible
|
||||
if not ftrack_accessible:
|
||||
if not printed_ftrack_error:
|
||||
log.warning("Can't access Ftrack {}".format(ftrack_url))
|
||||
|
||||
if self.thread_socket_server is not None:
|
||||
self.thread_socket_server.stop()
|
||||
self.thread_socket_server.join()
|
||||
self.thread_socket_server = None
|
||||
self.bool_action_thread_running = False
|
||||
self.set_menu_visibility()
|
||||
|
||||
printed_ftrack_error = True
|
||||
|
||||
time.sleep(1)
|
||||
continue
|
||||
log.info(
|
||||
"Connected to Ftrack server. Running actions session"
|
||||
)
|
||||
try:
|
||||
self.bool_action_server_running = True
|
||||
|
||||
printed_ftrack_error = False
|
||||
|
||||
# Run backup thread which does not requeire mongo to work
|
||||
if self.thread_socket_server is None:
|
||||
if failed_count < max_fail_count:
|
||||
self.thread_socket_server = socket_thread.SocketThread(
|
||||
thread_name, thread_port, subprocess_path
|
||||
)
|
||||
self.thread_socket_server.start()
|
||||
self.bool_action_thread_running = True
|
||||
self.set_menu_visibility()
|
||||
|
||||
elif failed_count == max_fail_count:
|
||||
log.warning((
|
||||
"Action server failed {} times."
|
||||
" I'll try to run again {}s later"
|
||||
).format(
|
||||
str(max_fail_count), str(wait_time_after_max_fail))
|
||||
)
|
||||
failed_count += 1
|
||||
|
||||
elif ((
|
||||
datetime.datetime.now() - last_failed
|
||||
).seconds > wait_time_after_max_fail):
|
||||
failed_count = 0
|
||||
|
||||
# If thread failed test Ftrack and Mongo connection
|
||||
elif not self.thread_socket_server.isAlive():
|
||||
self.thread_socket_server_thread.join()
|
||||
self.thread_socket_server = None
|
||||
ftrack_accessible = False
|
||||
|
||||
self.bool_action_thread_running = False
|
||||
self.set_menu_visibility()
|
||||
self.action_server.run_server()
|
||||
if self.bool_action_thread_running:
|
||||
log.debug("Ftrack action server has stopped")
|
||||
except Exception:
|
||||
log.warning(
|
||||
"Ftrack Action server crashed. Trying to connect again",
|
||||
exc_info=True
|
||||
)
|
||||
self.bool_action_server_running = False
|
||||
self.set_menu_visibility()
|
||||
first_check = True
|
||||
|
||||
_last_failed = datetime.datetime.now()
|
||||
delta_time = (_last_failed - last_failed).seconds
|
||||
if delta_time < min_fail_seconds:
|
||||
failed_count += 1
|
||||
else:
|
||||
failed_count = 0
|
||||
last_failed = _last_failed
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
self.bool_action_thread_running = False
|
||||
self.bool_action_server_running = False
|
||||
self.set_menu_visibility()
|
||||
|
||||
def reset_action_server(self):
|
||||
self.stop_action_server()
|
||||
|
|
@ -126,16 +198,18 @@ class FtrackModule:
|
|||
|
||||
def stop_action_server(self):
|
||||
try:
|
||||
self.bool_action_thread_running = False
|
||||
self.action_server.stop_session()
|
||||
self.bool_action_server_running = False
|
||||
if self.thread_socket_server is not None:
|
||||
self.thread_socket_server.stop()
|
||||
self.thread_socket_server.join()
|
||||
self.thread_socket_server = None
|
||||
|
||||
if self.thread_action_server is not None:
|
||||
self.thread_action_server.join()
|
||||
self.thread_action_server = None
|
||||
|
||||
log.info("Ftrack action server was forced to stop")
|
||||
|
||||
self.bool_action_server_running = False
|
||||
self.set_menu_visibility()
|
||||
except Exception:
|
||||
log.warning(
|
||||
"Error has happened during Killing action server",
|
||||
|
|
@ -201,9 +275,9 @@ class FtrackModule:
|
|||
self.stop_timer_thread()
|
||||
return
|
||||
|
||||
self.aRunActionS.setVisible(not self.bool_action_thread_running)
|
||||
self.aRunActionS.setVisible(not self.bool_action_server_running)
|
||||
self.aResetActionS.setVisible(self.bool_action_thread_running)
|
||||
self.aStopActionS.setVisible(self.bool_action_thread_running)
|
||||
self.aStopActionS.setVisible(self.bool_action_server_running)
|
||||
|
||||
if self.bool_timer_event is False:
|
||||
self.start_timer_thread()
|
||||
|
|
|
|||
67
pype/lib.py
|
|
@ -196,9 +196,13 @@ def any_outdated():
|
|||
if representation in checked:
|
||||
continue
|
||||
|
||||
representation_doc = io.find_one({"_id": io.ObjectId(representation),
|
||||
"type": "representation"},
|
||||
projection={"parent": True})
|
||||
representation_doc = io.find_one(
|
||||
{
|
||||
"_id": io.ObjectId(representation),
|
||||
"type": "representation"
|
||||
},
|
||||
projection={"parent": True}
|
||||
)
|
||||
if representation_doc and not is_latest(representation_doc):
|
||||
return True
|
||||
elif not representation_doc:
|
||||
|
|
@ -308,27 +312,38 @@ def switch_item(container,
|
|||
representation_name = representation["name"]
|
||||
|
||||
# Find the new one
|
||||
asset = io.find_one({"name": asset_name, "type": "asset"})
|
||||
asset = io.find_one({
|
||||
"name": asset_name,
|
||||
"type": "asset"
|
||||
})
|
||||
assert asset, ("Could not find asset in the database with the name "
|
||||
"'%s'" % asset_name)
|
||||
|
||||
subset = io.find_one({"name": subset_name,
|
||||
"type": "subset",
|
||||
"parent": asset["_id"]})
|
||||
subset = io.find_one({
|
||||
"name": subset_name,
|
||||
"type": "subset",
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
assert subset, ("Could not find subset in the database with the name "
|
||||
"'%s'" % subset_name)
|
||||
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[('name', -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[('name', -1)]
|
||||
)
|
||||
|
||||
assert version, "Could not find a version for {}.{}".format(
|
||||
asset_name, subset_name
|
||||
)
|
||||
|
||||
representation = io.find_one({"name": representation_name,
|
||||
"type": "representation",
|
||||
"parent": version["_id"]})
|
||||
representation = io.find_one({
|
||||
"name": representation_name,
|
||||
"type": "representation",
|
||||
"parent": version["_id"]}
|
||||
)
|
||||
|
||||
assert representation, ("Could not find representation in the database with"
|
||||
" the name '%s'" % representation_name)
|
||||
|
|
@ -366,7 +381,10 @@ def get_asset(asset_name=None):
|
|||
if not asset_name:
|
||||
asset_name = avalon.api.Session["AVALON_ASSET"]
|
||||
|
||||
asset_document = io.find_one({"name": asset_name, "type": "asset"})
|
||||
asset_document = io.find_one({
|
||||
"name": asset_name,
|
||||
"type": "asset"
|
||||
})
|
||||
if not asset_document:
|
||||
raise TypeError("Entity \"{}\" was not found in DB".format(asset_name))
|
||||
|
||||
|
|
@ -538,8 +556,7 @@ def get_subsets(asset_name,
|
|||
from avalon import io
|
||||
|
||||
# query asset from db
|
||||
asset_io = io.find_one({"type": "asset",
|
||||
"name": asset_name})
|
||||
asset_io = io.find_one({"type": "asset", "name": asset_name})
|
||||
|
||||
# check if anything returned
|
||||
assert asset_io, "Asset not existing. \
|
||||
|
|
@ -563,14 +580,20 @@ def get_subsets(asset_name,
|
|||
# Process subsets
|
||||
for subset in subsets:
|
||||
if not version:
|
||||
version_sel = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[("name", -1)])
|
||||
version_sel = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
else:
|
||||
assert isinstance(version, int), "version needs to be `int` type"
|
||||
version_sel = io.find_one({"type": "version",
|
||||
"parent": subset["_id"],
|
||||
"name": int(version)})
|
||||
version_sel = io.find_one({
|
||||
"type": "version",
|
||||
"parent": subset["_id"],
|
||||
"name": int(version)
|
||||
})
|
||||
|
||||
find_dict = {"type": "representation",
|
||||
"parent": version_sel["_id"]}
|
||||
|
|
|
|||
|
|
@ -31,32 +31,44 @@ class CollectTemplates(pyblish.api.InstancePlugin):
|
|||
asset_name = instance.data["asset"]
|
||||
project_name = api.Session["AVALON_PROJECT"]
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True, "data": True})
|
||||
project = io.find_one(
|
||||
{
|
||||
"type": "project",
|
||||
"name": project_name
|
||||
},
|
||||
projection={"config": True, "data": True}
|
||||
)
|
||||
|
||||
template = project["config"]["template"]["publish"]
|
||||
anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert asset, ("No asset found by the name '{}' "
|
||||
"in project '{}'".format(asset_name, project_name))
|
||||
silo = asset.get('silo')
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version = None
|
||||
version_number = 1
|
||||
if subset is not None:
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[("name", -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
# if there is a subset there ought to be version
|
||||
if version is not None:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import copy
|
|||
|
||||
import pype.api
|
||||
import pyblish
|
||||
from pypeapp import config
|
||||
|
||||
|
||||
class ExtractBurnin(pype.api.Extractor):
|
||||
|
|
@ -43,6 +44,9 @@ class ExtractBurnin(pype.api.Extractor):
|
|||
"intent": instance.context.data.get("intent", "")
|
||||
}
|
||||
|
||||
# Add datetime data to preparation data
|
||||
prep_data.update(config.get_datetime_data())
|
||||
|
||||
slate_frame_start = frame_start
|
||||
slate_frame_end = frame_end
|
||||
slate_duration = duration
|
||||
|
|
|
|||
|
|
@ -84,9 +84,11 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
|
|||
|
||||
project = io.find_one({"type": "project"})
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert all([project, asset]), ("Could not find current project or "
|
||||
"asset '%s'" % ASSET)
|
||||
|
|
@ -94,10 +96,14 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
|
|||
subset = self.get_subset(asset, instance)
|
||||
|
||||
# get next version
|
||||
latest_version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
{"name": True},
|
||||
sort=[("name", -1)])
|
||||
latest_version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
{"name": True},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
next_version = 1
|
||||
if latest_version is not None:
|
||||
|
|
@ -318,9 +324,11 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
|
|||
|
||||
def get_subset(self, asset, instance):
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]
|
||||
})
|
||||
|
||||
if subset is None:
|
||||
subset_name = instance.data["subset"]
|
||||
|
|
|
|||
|
|
@ -82,31 +82,40 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
project_name = api.Session["AVALON_PROJECT"]
|
||||
a_template = anatomy.templates
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True, "data": True})
|
||||
project = io.find_one(
|
||||
{"type": "project", "name": project_name},
|
||||
projection={"config": True, "data": True}
|
||||
)
|
||||
|
||||
template = a_template['publish']['path']
|
||||
# anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert asset, ("No asset found by the name '{}' "
|
||||
"in project '{}'".format(asset_name, project_name))
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version = None
|
||||
version_number = 1
|
||||
if subset is not None:
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[("name", -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
# if there is a subset there ought to be version
|
||||
if version is not None:
|
||||
|
|
|
|||
|
|
@ -153,9 +153,11 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
io.install()
|
||||
project = io.find_one({"type": "project"})
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert all([project, asset]), ("Could not find current project or "
|
||||
"asset '%s'" % ASSET)
|
||||
|
|
@ -163,10 +165,14 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
subset = self.get_subset(asset, instance)
|
||||
|
||||
# get next version
|
||||
latest_version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
{"name": True},
|
||||
sort=[("name", -1)])
|
||||
latest_version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
{"name": True},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
next_version = 1
|
||||
if latest_version is not None:
|
||||
|
|
@ -532,9 +538,11 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
filelink.create(src, dst, filelink.HARDLINK)
|
||||
|
||||
def get_subset(self, asset, instance):
|
||||
subset = io.find_one({"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]
|
||||
})
|
||||
|
||||
if subset is None:
|
||||
subset_name = instance.data["subset"]
|
||||
|
|
|
|||
|
|
@ -88,9 +88,11 @@ class IntegrateFrames(pyblish.api.InstancePlugin):
|
|||
|
||||
project = io.find_one({"type": "project"})
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": ASSET,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert all([project, asset]), ("Could not find current project or "
|
||||
"asset '%s'" % ASSET)
|
||||
|
|
@ -98,10 +100,14 @@ class IntegrateFrames(pyblish.api.InstancePlugin):
|
|||
subset = self.get_subset(asset, instance)
|
||||
|
||||
# get next version
|
||||
latest_version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
{"name": True},
|
||||
sort=[("name", -1)])
|
||||
latest_version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
{"name": True},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
next_version = 1
|
||||
if latest_version is not None:
|
||||
|
|
@ -251,9 +257,6 @@ class IntegrateFrames(pyblish.api.InstancePlugin):
|
|||
|
||||
self.log.debug("path_to_save: {}".format(path_to_save))
|
||||
|
||||
|
||||
|
||||
|
||||
representation = {
|
||||
"schema": "pype:representation-2.0",
|
||||
"type": "representation",
|
||||
|
|
@ -332,9 +335,11 @@ class IntegrateFrames(pyblish.api.InstancePlugin):
|
|||
|
||||
def get_subset(self, asset, instance):
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": instance.data["subset"]
|
||||
})
|
||||
|
||||
if subset is None:
|
||||
subset_name = instance.data["subset"]
|
||||
|
|
|
|||
|
|
@ -33,14 +33,22 @@ def _get_script():
|
|||
# Logic to retrieve latest files concerning extendFrames
|
||||
def get_latest_version(asset_name, subset_name, family):
|
||||
# Get asset
|
||||
asset_name = io.find_one({"type": "asset",
|
||||
"name": asset_name},
|
||||
projection={"name": True})
|
||||
asset_name = io.find_one(
|
||||
{
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
},
|
||||
projection={"name": True}
|
||||
)
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset_name["_id"]},
|
||||
projection={"_id": True, "name": True})
|
||||
subset = io.find_one(
|
||||
{
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset_name["_id"]
|
||||
},
|
||||
projection={"_id": True, "name": True}
|
||||
)
|
||||
|
||||
# Check if subsets actually exists (pre-run check)
|
||||
assert subset, "No subsets found, please publish with `extendFrames` off"
|
||||
|
|
@ -51,11 +59,15 @@ def get_latest_version(asset_name, subset_name, family):
|
|||
"data.endFrame": True,
|
||||
"parent": True}
|
||||
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"],
|
||||
"data.families": family},
|
||||
projection=version_projection,
|
||||
sort=[("name", -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"],
|
||||
"data.families": family
|
||||
},
|
||||
projection=version_projection,
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
assert version, "No version found, this is a bug"
|
||||
|
||||
|
|
|
|||
|
|
@ -116,9 +116,11 @@ class LookLoader(pype.maya.plugin.ReferenceLoader):
|
|||
shapes=True))
|
||||
nodes = set(nodes_list)
|
||||
|
||||
json_representation = io.find_one({"type": "representation",
|
||||
"parent": representation['parent'],
|
||||
"name": "json"})
|
||||
json_representation = io.find_one({
|
||||
"type": "representation",
|
||||
"parent": representation['parent'],
|
||||
"name": "json"
|
||||
})
|
||||
|
||||
# Load relationships
|
||||
shader_relation = api.get_representation_path(json_representation)
|
||||
|
|
|
|||
|
|
@ -429,33 +429,42 @@ class ExtractLook(pype.api.Extractor):
|
|||
a_template = anatomy.templates
|
||||
|
||||
project = io.find_one(
|
||||
{"type": "project", "name": project_name},
|
||||
projection={"config": True, "data": True},
|
||||
{
|
||||
"type": "project",
|
||||
"name": project_name
|
||||
},
|
||||
projection={"config": True, "data": True}
|
||||
)
|
||||
|
||||
template = a_template["publish"]["path"]
|
||||
# anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one(
|
||||
{"type": "asset", "name": asset_name, "parent": project["_id"]}
|
||||
)
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert asset, ("No asset found by the name '{}' "
|
||||
"in project '{}'").format(asset_name, project_name)
|
||||
silo = asset.get("silo")
|
||||
|
||||
subset = io.find_one(
|
||||
{"type": "subset", "name": subset_name, "parent": asset["_id"]}
|
||||
)
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version = None
|
||||
version_number = 1
|
||||
if subset is not None:
|
||||
version = io.find_one(
|
||||
{"type": "version",
|
||||
"parent": subset["_id"]
|
||||
}, sort=[("name", -1)]
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
# if there is a subset there ought to be version
|
||||
|
|
|
|||
|
|
@ -38,9 +38,13 @@ class ValidateNodeIDsRelated(pyblish.api.InstancePlugin):
|
|||
invalid = list()
|
||||
|
||||
asset = instance.data['asset']
|
||||
asset_data = io.find_one({"name": asset,
|
||||
"type": "asset"},
|
||||
projection={"_id": True})
|
||||
asset_data = io.find_one(
|
||||
{
|
||||
"name": asset,
|
||||
"type": "asset"
|
||||
},
|
||||
projection={"_id": True}
|
||||
)
|
||||
asset_id = str(asset_data['_id'])
|
||||
|
||||
# We do want to check the referenced nodes as we it might be
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@ class ValidateRenderLayerAOVs(pyblish.api.InstancePlugin):
|
|||
"""Check if subset is registered in the database under the asset"""
|
||||
|
||||
asset = io.find_one({"type": "asset", "name": asset_name})
|
||||
is_valid = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
is_valid = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
return is_valid
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,10 @@ class CollectAssetInfo(pyblish.api.ContextPlugin):
|
|||
]
|
||||
|
||||
def process(self, context):
|
||||
asset_data = io.find_one({"type": "asset",
|
||||
"name": api.Session["AVALON_ASSET"]})
|
||||
asset_data = io.find_one({
|
||||
"type": "asset",
|
||||
"name": api.Session["AVALON_ASSET"]
|
||||
})
|
||||
self.log.info("asset_data: {}".format(asset_data))
|
||||
|
||||
context.data['handles'] = int(asset_data["data"].get("handles", 0))
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ class CollectNukeInstances(pyblish.api.ContextPlugin):
|
|||
hosts = ["nuke", "nukeassist"]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
asset_data = io.find_one({"type": "asset",
|
||||
"name": api.Session["AVALON_ASSET"]})
|
||||
asset_data = io.find_one({
|
||||
"type": "asset",
|
||||
"name": api.Session["AVALON_ASSET"]
|
||||
})
|
||||
|
||||
self.log.debug("asset_data: {}".format(asset_data["data"]))
|
||||
instances = []
|
||||
|
|
|
|||
|
|
@ -169,32 +169,44 @@ class ExtractVideoTracksLuts(pyblish.api.InstancePlugin):
|
|||
project_name = api.Session["AVALON_PROJECT"]
|
||||
a_template = anatomy.templates
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True, "data": True})
|
||||
project = io.find_one(
|
||||
{
|
||||
"type": "project",
|
||||
"name": project_name
|
||||
},
|
||||
projection={"config": True, "data": True}
|
||||
)
|
||||
|
||||
template = a_template['publish']['path']
|
||||
# anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert asset, ("No asset found by the name '{}' "
|
||||
"in project '{}'".format(asset_name, project_name))
|
||||
silo = asset.get('silo')
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version = None
|
||||
version_number = 1
|
||||
if subset is not None:
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[("name", -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
# if there is a subset there ought to be version
|
||||
if version is not None:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from avalon import io
|
|||
from pype.action import get_errored_instances_from_context
|
||||
import pype.api as pype
|
||||
|
||||
|
||||
@pyblish.api.log
|
||||
class RepairNukestudioVersionUp(pyblish.api.Action):
|
||||
label = "Version Up Workfile"
|
||||
|
|
@ -53,13 +54,17 @@ class ValidateVersion(pyblish.api.InstancePlugin):
|
|||
io.install()
|
||||
project = io.find_one({"type": "project"})
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": subset_name})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"parent": asset["_id"],
|
||||
"name": subset_name
|
||||
})
|
||||
|
||||
version_db = io.find_one({
|
||||
'type': 'version',
|
||||
|
|
|
|||
|
|
@ -77,32 +77,44 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
asset_name = instance.data["asset"]
|
||||
project_name = api.Session["AVALON_PROJECT"]
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True, "data": True})
|
||||
project = io.find_one(
|
||||
{
|
||||
"type": "project",
|
||||
"name": project_name
|
||||
},
|
||||
projection={"config": True, "data": True}
|
||||
)
|
||||
|
||||
template = project["config"]["template"]["publish"]
|
||||
# anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
asset = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]
|
||||
})
|
||||
|
||||
assert asset, ("No asset found by the name '{}' "
|
||||
"in project '{}'".format(asset_name, project_name))
|
||||
silo = asset.get('silo')
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
subset = io.find_one({
|
||||
"type": "subset",
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]
|
||||
})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version = None
|
||||
version_number = 1
|
||||
if subset is not None:
|
||||
version = io.find_one({"type": "version",
|
||||
"parent": subset["_id"]},
|
||||
sort=[("name", -1)])
|
||||
version = io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
|
||||
# if there is a subset there ought to be version
|
||||
if version is not None:
|
||||
|
|
|
|||
|
|
@ -170,8 +170,10 @@ def switch(asset_name, filepath=None, new=True):
|
|||
assert asset, "Could not find '%s' in the database" % asset_name
|
||||
|
||||
# Get current project
|
||||
self._project = io.find_one({"type": "project",
|
||||
"name": api.Session["AVALON_PROJECT"]})
|
||||
self._project = io.find_one({
|
||||
"type": "project",
|
||||
"name": api.Session["AVALON_PROJECT"]
|
||||
})
|
||||
|
||||
# Go to comp
|
||||
if not filepath:
|
||||
|
|
|
|||
|
|
@ -462,8 +462,12 @@ def update_scene(set_container, containers, current_data, new_data, new_file):
|
|||
# Check whether the conversion can be done by the Loader.
|
||||
# They *must* use the same asset, subset and Loader for
|
||||
# `api.update` to make sense.
|
||||
old = io.find_one({"_id": io.ObjectId(representation_current)})
|
||||
new = io.find_one({"_id": io.ObjectId(representation_new)})
|
||||
old = io.find_one({
|
||||
"_id": io.ObjectId(representation_current)
|
||||
})
|
||||
new = io.find_one({
|
||||
"_id": io.ObjectId(representation_new)
|
||||
})
|
||||
is_valid = compare_representations(old=old, new=new)
|
||||
if not is_valid:
|
||||
log.error("Skipping: %s. See log for details.",
|
||||
|
|
|
|||
1
setup/nuke/nuke_path/KnobScripter/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
import knob_scripter
|
||||
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_clearConsole.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_download.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_exitnode.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_pick.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_prefs.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_prefs2.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_refresh.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_run.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_save.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_search.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
setup/nuke/nuke_path/KnobScripter/icons/icon_snippets.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
4196
setup/nuke/nuke_path/KnobScripter/knob_scripter.py
Normal file
|
|
@ -1,4 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import atom_server
|
||||
import KnobScripter
|
||||
|
||||
from pype.nuke.lib import (
|
||||
writes_version_sync,
|
||||
|
|
|
|||