def on_attribute_change(self, obj, attr, *_): """Handle attributes changing value. See on_action() docstring regarding exceptions. """ attr_name = attr.get_name() verbose_errors = obj.get_attribute("verbose_errors").get_bool() try: if attr_name == "project": projects_ui.handle_project(obj, attr) elif attr_name == "use_custom_frames": frames_ui.handle_use_custom_frames(obj, attr) elif attr_name == "use_scout_frames": frames_ui.handle_use_scout_frames(obj, attr) elif attr_name == "custom_frames": frames_ui.handle_custom_frames(obj, attr) elif attr_name == "scout_frames": frames_ui.handle_scout_frames(obj, attr) elif attr_name == "chunk_size": frames_ui.handle_chunk_size(obj, attr) elif attr_name == "images": frames_ui.handle_images(obj, attr) elif attr_name == "notify": notifications_ui.notify_changed(obj, attr) elif attr_name == "email_addresses": notifications_ui.handle_email_addresses(obj, attr) else: pass except Exception as ex: if verbose_errors: ix.log_warning(traceback.format_exc()) else: ix.log_warning(ex.message)
def handle_email_addresses(obj, _): """Validate email addresses when attribute changes.""" val = obj.get_attribute("email_addresses").get_string().strip(',').strip() result = bool(val) for address in [x.strip() for x in val.split(',')]: if not SIMPLE_EMAIL_RE.match(address): result = False break if not result: ix.log_warning("Email addresses are invalid.")
def destroy_selected(self): """Remove the selected items. Also remove from the item_list. """ indices = self._get_selected_indices() if not indices: ix.log_warning("Nothing selected") return self.destroy_selected_items() self.refresh() self._remove_from_sync_itet(indices)
def handle_email_addresses(obj, _): """ Validate email addresses when attribute changes. Args: obj (ConductorJob): Item from which to get notification data """ val = obj.get_attribute("email_addresses").get_string().strip(",").strip() result = bool(val) for address in [x.strip() for x in val.split(",")]: if not SIMPLE_EMAIL_RE.match(address): result = False break if not result: ix.log_warning("Email addresses are invalid.")
def get_row(self, row_number): """ Get all the columns data for the row specified as parameter Args: row_number (int): The row to affect Returns: ShadingLayerRow: A simple OOP object that will allow you to get the column data for this row """ if not row_number in range(self.get_module().get_rules().get_count()): ix.log_warning("The row `{}` can't be found in `{}`".format( row_number, self)) return None result = ShadingLayerRow(self, row_number) for k in self._default_columns: setattr(result, k, self.get_module().get_rule_value(row_number, k)) return result
def submit(*args): """ Validate and submit directly. """ node = args[0] state, fn = check_need_save(node, SUBMIT_DIRECT) if state not in [ SAVE_STATE_UNMODIFIED, SAVE_STATE_SAVED, SAVE_STATE_DONT_CARE ]: ix.log_warning("Submission cancelled.") return _validate_images(node) _validate_packages(node) with cu.waiting_cursor(): submission = Submission(node) responses = submission.submit() preview_ui.show_submission_responses(responses)
def on_attribute_change(self, obj, attr, *_): """ Handles attributes changing value. Args: obj (ConductorJob): The scripted class instance. attr (OfAttr): The attribute that changed. """ attr_name = attr.get_name() verbose_errors = obj.get_attribute("show_tracebacks").get_bool() try: if attr_name == "conductor_project_name": projects_ui.handle_project(obj, attr) elif attr_name == "use_custom_frames": frames_ui.handle_use_custom_frames(obj, attr) elif attr_name == "use_scout_frames": frames_ui.handle_use_scout_frames(obj, attr) elif attr_name == "custom_frames": frames_ui.handle_custom_frames(obj, attr) elif attr_name == "scout_frames": frames_ui.handle_scout_frames(obj, attr) elif attr_name == "chunk_size": frames_ui.handle_chunk_size(obj, attr) elif attr_name == "images_and_layers": frames_ui.handle_images(obj, attr) elif attr_name == "notify": notifications_ui.notify_changed(obj, attr) elif attr_name == "email_addresses": notifications_ui.handle_email_addresses(obj, attr) elif attr_name == "conductor_log_level": debug_ui.handle_log_level(obj, attr) else: pass except RuntimeError as ex: if verbose_errors: ix.log_warning(traceback.format_exc()) else: ix.log_warning(ex.message)
def on_action(self, action, obj, data): """ Handles any button press in the Attribute Editor. Args: action (str): Name of the action is a nice version of the button label. obj (ConductorJob): The scripted class instance. data (dict): Extra information about the event """ action_name = action.get_name() verbose_errors = obj.get_attribute("show_tracebacks").get_bool() # We need to wrap everything in a try/except because Clarisse # crashes if an exception is thrown from a scripted class. See # https://www.isotropix.com/user/bugtracker/363 . try: if action_name == "manage_extra_uploads": extra_uploads_ui.build(obj, data) elif action_name == "manage_extra_environment": environment_ui.build(obj, data) elif action_name == "preflight": refresh.refresh(obj) submit_actions.preview(obj, data) elif action_name == "submit": refresh.refresh(obj) submit_actions.submit(obj, data) elif action_name == "connect": refresh.refresh(obj, force=True) elif action_name == "best_chunk_size": frames_ui.handle_best_chunk_size(obj, data) elif action_name == "reload": reload(reloader) else: pass except RuntimeError as ex: if verbose_errors: ix.log_warning(traceback.format_exc()) else: ix.log_warning(ex.message)
def preview(*args): """ Validate and show the script in a panel. Submission can be invoked from the preview panel. """ node = args[0] state, _ = check_need_save(node, PREVIEW_FIRST) if state == SAVE_STATE_CANCELLED: ix.log_warning("Preflight cancelled.") return can_submit = state in [ SAVE_STATE_UNMODIFIED, SAVE_STATE_SAVED, SAVE_STATE_DONT_CARE, ] _validate(node) with cu.waiting_cursor(): submission = Submission(node) preview_ui.build(submission, can_submit=can_submit)
def on_action(self, action, obj, data): """Handle any button press in the UI. We need to wrap everything in a try because Clarisse crashes if an exception is thrown from a scripted class. See https://www.isotropix.com/user/bugtracker/363 . """ action_name = action.get_name() verbose_errors = obj.get_attribute("verbose_errors").get_bool() try: if action_name == "choose_packages": packages_ui.build(obj, data) elif action_name == "manage_extra_uploads": extra_uploads_ui.build(obj, data) elif action_name == "manage_extra_environment": environment_ui.build(obj, data) elif action_name == "preview": self.refresh(obj) submit_actions.preview(obj, data) elif action_name == "submit": self.refresh(obj) submit_actions.submit(obj, data) elif action_name == "setup": self.refresh(obj, force=True) elif action_name == "best_chunk_size": frames_ui.handle_best_chunk_size(obj, data) elif action_name == "add_metadata": raise NotImplementedError elif action_name == "reload": reload(reloader) else: pass except Exception as ex: if verbose_errors: ix.log_warning(traceback.format_exc()) else: ix.log_warning(ex.message)
def add_custom_attribute(self, attr_name, kindof, group_name, array_length=1, num_range=None, ui_range=None, texturable=False, animatable=False, shading_var=False, allow_expression=False): """ Add a custom attribute to the current item. Args: attr_name (str): name of the future attributes kindof (str): Kindof attribute you want to create (long, double, bool, string, rgba...) group_name (str): Name of the group that will live the new attr (Kinematics, visibility...) array_length (int, optional): If the attribute has be be an array type (Like translate or resolution) set the array size here. Defaults to 1. num_range (list[int], optional): Give a min/max range of the attribute. Defaults to None. ui_range (list[int], optional): Give a min/max range of the UI in the attr editor. Defaults to None. texturable (bool, optional): Allow the attr to be texturable. Defaults to False. animatable (bool, optional): Allow the attr to be animatable. Defaults to False. shading_var (bool, optional): Allow the attr to be shading_var. Defaults to False. allow_expression (bool, optional): Allow the attr to be texturable (Due to a clarisse,s bug it's all the time True). Defaults to False. Returns: None|Attribute: If the attribute can't be created for what ever reason it returns None else it return an Attribute instance. """ if self.attribute_exists(attr_name): ix.log_warning("An attribute with the same name already exists.") return None mapping_name_vhint = { "angle": { "vhint": "VISUAL_HINT_ANGLE", "kindof": 2 }, "area": { "vhint": "VISUAL_HINT_AREA", "kindof": 2 }, "bool": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 0 }, "color": { "vhint": "VISUAL_HINT_COLOR", "kindof": 2 }, "curve": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 7 }, "distance": { "vhint": "VISUAL_HINT_DISTANCE", "kindof": 2 }, "double": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 2 }, "file": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 4 }, "filename_open": { "vhint": "VISUAL_HINT_FILENAME_OPEN", "kindof": 3 }, "filename_save": { "vhint": "VISUAL_HINT_FILENAME_SAVE", "kindof": 3 }, "folder": { "vhint": "VISUAL_HINT_FOLDER", "kindof": 3 }, "frame": { "vhint": "VISUAL_HINT_FRAME", "kindof": 1 }, "frequency": { "vhint": "VISUAL_HINT_FREQUENCY", "kindof": 2 }, "gradient": { "vhint": "VISUAL_HINT_GRADIENT", "kindof": 7 }, "l": { "vhint": "VISUAL_HINT_L", "kindof": 2 }, "la": { "vhint": "VISUAL_HINT_LA", "kindof": 2 }, "long": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 1 }, "memsize": { "vhint": "VISUAL_HINT_MEMSIZE", "kindof": 2 }, "multiline": { "vhint": "VISUAL_HINT_MULTILINE", "kindof": 2 }, "percentage": { "vhint": "VISUAL_HINT_PERCENTAGE", "kindof": 2 }, "pixel": { "vhint": "VISUAL_HINT_PIXEL", "kindof": 1 }, "rgb": { "vhint": "VISUAL_HINT_RGB", "kindof": 2 }, "rgba": { "vhint": "VISUAL_HINT_RGBA", "kindof": 2 }, "sample": { "vhint": "VISUAL_HINT_SAMPLE", "kindof": 1 }, "sample_per_pixel": { "vhint": "VISUAL_HINT_SAMPLE_PER_PIXEL", "kindof": 1 }, "scale": { "vhint": "VISUAL_HINT_SCALE", "kindof": 2 }, "script": { "vhint": "VISUAL_HINT_SCRIPT", "kindof": 3 }, "second": { "vhint": "VISUAL_HINT_SECOND", "kindof": 2 }, "string": { "vhint": "VISUAL_HINT_DEFAULT", "kindof": 3 }, "subframe": { "vhint": "VISUAL_HINT_SUBFRAME", "kindof": 2 }, "subpixel": { "vhint": "VISUAL_HINT_SUBPIXEL", "kindof": 2 }, "subsample": { "vhint": "VISUAL_HINT_SUBSAMPLE", "kindof": 2 }, "time": { "vhint": "VISUAL_HINT_TIME", "kindof": 2 }, "watt": { "vhint": "VISUAL_HINT_WATT", "kindof": 2 }, } presets = { "color": { "array_length": 3 }, "la": { "array_length": 2 }, "rgb": { "array_length": 3 }, "rgba": { "array_length": 4 }, } if not kindof in mapping_name_vhint.keys(): ix.log_warning( "There is not type `{}`. You can pick one of the following ones:\n{}" .format(kindof, mapping_name_vhint)) if kindof in presets: for var, value in presets[kindof].items(): if var == "array_length": array_length = value container = "CONTAINER_ARRAY" if array_length > 1 else "CONTAINER_SINGLE" result_mapping = { "container": container, "vhint": mapping_name_vhint[kindof]["vhint"], "group": group_name, "count": array_length, "num_min": None if not num_range else num_range[0], "num_max": None if not num_range else num_range[1], "ui_min": None if not ui_range else ui_range[0], "ui_max": None if not ui_range else ui_range[1], "texturable": texturable, "animatable": animatable, "shading_var": shading_var, "allow_expression": allow_expression, } headers = [] values = [] for header, value in result_mapping.items(): if value: headers.append(header) values.append(str(value)) ix.cmds.CreateCustomAttribute([str(self.get_ix_node())], attr_name, mapping_name_vhint[kindof]["kindof"], headers, values) return self.get_attribute(attr_name)