diff --git a/pyblish_qml/control.py b/pyblish_qml/control.py index 8885dc2a..617a6156 100644 --- a/pyblish_qml/control.py +++ b/pyblish_qml/control.py @@ -1,6 +1,7 @@ import json import time +import math import collections # Dependencies @@ -852,6 +853,7 @@ def on_run(plugins): def on_discover(plugins, context): collectors = list() + model = self.data["models"]["item"] # For backwards compatibility check for existance of # "plugins_by_targets" method. @@ -859,7 +861,7 @@ def on_discover(plugins, context): plugins = pyblish.api.plugins_by_targets(plugins, self.targets) for plugin in plugins: - self.data["models"]["item"].add_plugin(plugin.to_json()) + model.add_plugin(plugin.to_json()) # Sort out which of these are Collectors if not pyblish.lib.inrange( @@ -867,6 +869,11 @@ def on_discover(plugins, context): base=pyblish.api.Collector.order): continue + if plugin.order >= context.data["postCollectOrder"]: + model.plugins[-1].verb = "Additional" + model.add_section("Additional") + continue + if not plugin.active: continue @@ -895,6 +902,73 @@ def on_reset(): util.defer(self.host.reset, callback=on_reset) + def post_collect(self, on_post_collected): + + post_collect_order = self.host.cached_context.data["postCollectOrder"] + + def on_finished(context): + model = self.data["models"]["item"] + + # Compute compatibility + for plugin in model.plugins: + if plugin.instanceEnabled: + instances = pyblish.logic.instances_by_plugin(context, + plugin) + plugin.compatibleInstances = list(i.id for i in instances) + else: + plugin.compatibleInstances = [context.id] + + model.reorder(context) + model.update_compatibility() + + # Hidden sections + for section in model.sections: + if section.name in settings.HiddenSections: + self.hideSection(True, section.name) + + on_post_collected() + + def on_run(): + """Fetch instances in their current state, right after reset""" + util.defer(self.host.context, + callback=lambda context: on_finished(context)) + + def on_data_received(args): + self.run(*args, callback=on_run) + + def get_data(): + """Get post collector plugins and instances""" + model = self.data["models"]["item"] + + host_plugins = dict((p.id, p) for p in self.host.cached_discover) + host_context = dict((i.id, i) for i in self.host.cached_context) + + collectors = list() + instances = list() + + for plugin in models.ItemIterator(model.plugins): + # Sort out which of these are Post Collectors + if not pyblish.lib.inrange( + number=plugin.order, + base=pyblish.api.Collector.order): + continue + + if plugin.order < post_collect_order: + continue + + collectors.append(host_plugins[plugin.id]) + + for instance in models.ItemIterator(model.instances): + instances.append(host_context[instance.id]) + + return collectors, instances + + util.defer(get_data, callback=on_data_received) + + def _use_post_collect(self): + context = self.host.cached_context + return not math.isnan(context.data["postCollectOrder"]) + @QtCore.Slot() def publish(self): """Start asynchonous publishing @@ -931,6 +1005,9 @@ def get_data(): return plugins, instances + def on_post_collected(): + util.defer(get_data, callback=on_data_received) + def on_data_received(args): self.run(*args, callback=on_finished) @@ -950,7 +1027,10 @@ def on_finished(): self.info.emit("Published, with errors..") break - util.defer(get_data, callback=on_data_received) + if self._use_post_collect(): + self.post_collect(on_post_collected) + else: + util.defer(get_data, callback=on_data_received) @QtCore.Slot() def validate(self): @@ -986,13 +1066,19 @@ def get_data(): return plugins, instances + def on_post_collected(): + util.defer(get_data, callback=on_data_received) + def on_data_received(args): self.run(*args, callback=on_finished) def on_finished(): self.host.emit("validated", context=None) - util.defer(get_data, callback=on_data_received) + if self._use_post_collect(): + self.post_collect(on_post_collected) + else: + util.defer(get_data, callback=on_data_received) def run(self, plugins, context, callback=None, callback_args=None): """Commence asynchronous tasks diff --git a/pyblish_qml/ipc/formatting.py b/pyblish_qml/ipc/formatting.py index 0c8765d8..0cae2378 100644 --- a/pyblish_qml/ipc/formatting.py +++ b/pyblish_qml/ipc/formatting.py @@ -142,6 +142,7 @@ def format_data(data): "port", "user", "connectTime", + "postCollectOrder", "pyblishVersion", "pyblishRPCVersion", "pythonVersion") @@ -194,6 +195,13 @@ def format_context(context): } +def format_post_collect_order(order): + try: + return float(order) + except (TypeError, ValueError): + return float("NaN") + + def format_plugins(plugins): """Serialise multiple plug-in diff --git a/pyblish_qml/ipc/service.py b/pyblish_qml/ipc/service.py index 9f8354d5..254f8b3a 100644 --- a/pyblish_qml/ipc/service.py +++ b/pyblish_qml/ipc/service.py @@ -28,6 +28,7 @@ def __init__(self): self._context = None self._plugins = None self._provider = None + self._post_collect = None self.reset() @@ -51,6 +52,8 @@ def reset(self): self._context = pyblish.api.Context() self._plugins = pyblish.api.discover() self._provider = pyblish.plugin.Provider() + self._post_collect = formatting.format_post_collect_order( + os.environ.get("PYBLISH_QML_POST_COLLECT")) def context(self): # Append additional metadata to context @@ -60,6 +63,7 @@ def context(self): for key, value in {"host": hosts, "port": int(port), "user": getpass.getuser(), + "postCollectOrder": self._post_collect, "connectTime": pyblish.lib.time(), "pyblishVersion": pyblish.version, "pythonVersion": sys.version}.items(): diff --git a/pyblish_qml/models.py b/pyblish_qml/models.py index 1190c765..4fffcbd0 100644 --- a/pyblish_qml/models.py +++ b/pyblish_qml/models.py @@ -82,6 +82,7 @@ "port": 0, "host": "default", "user": "default", + "postCollectOrder": float("NaN"), "connectTime": "default", "pythonVersion": "default", "pyblishVersion": "default", diff --git a/pyblish_qml/qml/delegates/ContextDelegate.qml b/pyblish_qml/qml/delegates/ContextDelegate.qml index 8aa3af4a..305377a4 100644 --- a/pyblish_qml/qml/delegates/ContextDelegate.qml +++ b/pyblish_qml/qml/delegates/ContextDelegate.qml @@ -47,6 +47,10 @@ BaseDelegate { "key": "Targets", "value": object.targets }, + { + "key": "Post Collect", + "value": object.postCollectOrder + }, { "key": "Connected", "value": Date(Date.parse(object.connectTime))