def custom_attributes_from_file(self, session, event):
        presets = config.get_presets()['ftrack']['ftrack_custom_attributes']

        for cust_attr_data in presets:
            cust_attr_name = cust_attr_data.get('label',
                                                cust_attr_data.get('key'))
            try:
                data = {}
                # Get key, label, type
                data.update(self.get_required(cust_attr_data))
                # Get hierachical/ entity_type/ object_id
                data.update(self.get_entity_type(cust_attr_data))
                # Get group, default, security roles
                data.update(self.get_optional(cust_attr_data))
                # Process data
                self.process_attribute(data)

            except CustAttrException as cae:
                if cust_attr_name:
                    msg = 'Custom attribute error "{}" - {}'.format(
                        cust_attr_name, str(cae))
                else:
                    msg = 'Custom attribute error - {}'.format(str(cae))
                self.log.warning(msg, exc_info=True)
                self.show_message(event, msg)

        return True
Example #2
0
    def __init__(self, tray_widget, main_window):
        self.tray_widget = tray_widget
        self.main_window = main_window

        self.log = Logger().get_logger(self.__class__.__name__)

        self.modules = {}
        self.services = {}
        self.services_submenu = None

        self.errors = []

        CURRENT_DIR = os.path.dirname(__file__)
        self.modules_imports = config.load_json(
            os.path.join(CURRENT_DIR, "modules_imports.json"))
        presets = config.get_presets(first_run=True)
        menu_items = presets["tray"]["menu_items"]
        try:
            self.modules_usage = menu_items["item_usage"]
        except Exception:
            self.modules_usage = {}
            self.log.critical("Couldn't find modules usage data.")

        self.module_attributes = menu_items.get("attributes") or {}

        self.icon_run = QtGui.QIcon(
            resources.get_resource("icons", "circle_green.png"))
        self.icon_stay = QtGui.QIcon(
            resources.get_resource("icons", "circle_orange.png"))
        self.icon_failed = QtGui.QIcon(
            resources.get_resource("icons", "circle_red.png"))
Example #3
0
    def refresh(self):
        has_families = False
        presets = config.get_presets().get('standalone_publish', {})

        for key, creator in presets.get('families', {}).items():
            creator = namedtuple("Creator", creator.keys())(*creator.values())

            label = creator.label or creator.family
            item = QtWidgets.QListWidgetItem(label)
            item.setData(QtCore.Qt.ItemIsEnabled, True)
            item.setData(HelpRole, creator.help or "")
            item.setData(FamilyRole, creator.family)
            item.setData(PluginRole, creator)
            item.setData(PluginKeyRole, key)
            item.setData(ExistsRole, False)
            self.list_families.addItem(item)

            has_families = True

        if not has_families:
            item = QtWidgets.QListWidgetItem("No registered families")
            item.setData(QtCore.Qt.ItemIsEnabled, False)
            self.list_families.addItem(item)

        self.list_families.setCurrentItem(self.list_families.item(0))
Example #4
0
def clockify_module_registration():
    module_name = "Clockify"

    menu_items = config.get_presets()["tray"]["menu_items"]
    if not menu_items["item_usage"][module_name]:
        return

    api_key = os.environ.get("CLOCKIFY_API_KEY")
    if not api_key:
        log.warning("Clockify API key is not set.")
        return

    workspace_name = os.environ.get("CLOCKIFY_WORKSPACE")
    if not workspace_name:
        workspace_name = (menu_items.get("attributes",
                                         {}).get(module_name,
                                                 {}).get("workspace_name", {}))

    if not workspace_name:
        log.warning("Clockify Workspace is not set.")
        return

    os.environ["CLOCKIFY_WORKSPACE"] = workspace_name

    from pype.modules.clockify.constants import CLOCKIFY_FTRACK_SERVER_PATH

    current = os.environ.get("FTRACK_EVENTS_PATH") or ""
    if current:
        current += os.pathsep
    os.environ["FTRACK_EVENTS_PATH"] = current + CLOCKIFY_FTRACK_SERVER_PATH
    return True
Example #5
0
def imprint_attributes(plugin):
    """
    Load presets by class and set them as attributes (if found)

    :param plugin: plugin instance
    :type plugin: instance
    """
    file = inspect.getfile(plugin.__class__)
    file = os.path.normpath(file)
    plugin_kind = file.split(os.path.sep)[-2:-1][0]
    plugin_host = file.split(os.path.sep)[-3:-2][0]
    plugin_name = type(plugin).__name__
    try:
        config_data = config.get_presets(
        )['plugins'][plugin_host][plugin_kind][plugin_name]  # noqa: E501
    except KeyError:
        print("preset not found")
        return

    for option, value in config_data.items():
        if option == "enabled" and value is False:
            setattr(plugin, "active", False)
        else:
            setattr(plugin, option, value)
            print("setting {}: {} on {}".format(option, value, plugin_name))
Example #6
0
    def load(self, context, name, namespace, options):

        import maya.cmds as cmds
        import avalon.maya.lib as lib
        from avalon.maya.pipeline import containerise
        import mtoa.ui.arnoldmenu
        import pymel.core as pm

        version = context['version']
        version_data = version.get("data", {})

        self.log.info("version_data: {}\n".format(version_data))

        frameStart = version_data.get("frameStart", None)

        asset = context['asset']['name']
        namespace = namespace or lib.unique_namespace(
            asset + "_",
            prefix="_" if asset[0].isdigit() else "",
            suffix="_",
        )

        # cmds.loadPlugin("gpuCache", quiet=True)

        # Root group
        label = "{}:{}".format(namespace, name)
        root = pm.group(name=label, empty=True)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']

        c = colors.get('ass')
        if c is not None:
            cmds.setAttr(root + ".useOutlinerColor", 1)
            cmds.setAttr(root + ".outlinerColor", c[0], c[1], c[2])

        # Create transform with shape
        transform_name = label + "_ASS"
        # transform = pm.createNode("transform", name=transform_name,
        #                             parent=root)

        standinShape = pm.PyNode(mtoa.ui.arnoldmenu.createStandIn())
        standin = standinShape.getParent()
        standin.rename(transform_name)

        pm.parent(standin, root)

        # Set the standin filepath
        standinShape.dso.set(self.fname)
        if frameStart is not None:
            standinShape.useFrameExtension.set(1)

        nodes = [root, standin]
        self[:] = nodes

        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
Example #7
0
def get_families():
    families = []
    paths = config.get_presets().get("djv_view",
                                     {}).get("config",
                                             {}).get("djv_paths", [])
    for path in paths:
        if os.path.exists(path):
            families.append("*")
            break
    return families
Example #8
0
    def load(self, context, name=None, namespace=None, data=None):

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "yeticache"

        # Build namespace
        asset = context["asset"]
        if namespace is None:
            namespace = self.create_namespace(asset["name"])

        # Ensure Yeti is loaded
        if not cmds.pluginInfo("pgYetiMaya", query=True, loaded=True):
            cmds.loadPlugin("pgYetiMaya", quiet=True)

        # Get JSON
        fbase = re.search(r'^(.+)\.(\d+|#+)\.fur', self.fname)
        if not fbase:
            raise RuntimeError('Cannot determine fursettings file path')
        settings_fname = "{}.fursettings".format(fbase.group(1))
        with open(settings_fname, "r") as fp:
            fursettings = json.load(fp)

        # Check if resources map exists
        # Get node name from JSON
        if "nodes" not in fursettings:
            raise RuntimeError("Encountered invalid data, expect 'nodes' in "
                               "fursettings.")

        node_data = fursettings["nodes"]
        nodes = self.create_nodes(namespace, node_data)

        group_name = "{}:{}".format(namespace, name)
        group_node = cmds.group(nodes, name=group_name)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']

        c = colors.get(family)
        if c is not None:
            cmds.setAttr(group_name + ".useOutlinerColor", 1)
            cmds.setAttr(group_name + ".outlinerColor", c[0], c[1], c[2])

        nodes.append(group_node)

        self[:] = nodes

        return pipeline.containerise(name=name,
                                     namespace=namespace,
                                     nodes=nodes,
                                     context=context,
                                     loader=self.__class__.__name__)
Example #9
0
 def set_signal_times(self):
     try:
         timer_info = (config.get_presets().get('services').get(
             'timers_manager').get('timer'))
         full_time = int(float(timer_info['full_time']) * 60)
         message_time = int(float(timer_info['message_time']) * 60)
         self.time_show_message = full_time - message_time
         self.time_stop_timer = full_time
         return True
     except Exception:
         self.log.warning('Was not able to load presets for TimersManager')
         return False
Example #10
0
    def __init__(self, session, plugins_presets):
        '''Expects a ftrack_api.Session instance'''
        super().__init__(session, plugins_presets)
        self.djv_path = None

        self.config_data = config.get_presets()['djv_view']['config']
        self.set_djv_path()

        if self.djv_path is None:
            return

        self.allowed_types = self.config_data.get('file_ext',
                                                  ["img", "mov", "exr"])
Example #11
0
    def load(self, context, name, namespace, data):

        import maya.cmds as cmds
        import avalon.maya.lib as lib
        from avalon.maya.pipeline import containerise

        asset = context['asset']['name']
        namespace = namespace or lib.unique_namespace(
            asset + "_",
            prefix="_" if asset[0].isdigit() else "",
            suffix="_",
        )

        cmds.loadPlugin("gpuCache", quiet=True)

        # Root group
        label = "{}:{}".format(namespace, name)
        root = cmds.group(name=label, empty=True)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']
        c = colors.get('model')
        if c is not None:
            cmds.setAttr(root + ".useOutlinerColor", 1)
            cmds.setAttr(root + ".outlinerColor", c[0], c[1], c[2])

        # Create transform with shape
        transform_name = label + "_GPU"
        transform = cmds.createNode("transform",
                                    name=transform_name,
                                    parent=root)
        cache = cmds.createNode("gpuCache",
                                parent=transform,
                                name="{0}Shape".format(transform_name))

        # Set the cache filepath
        cmds.setAttr(cache + '.cacheFileName', self.fname, type="string")
        cmds.setAttr(cache + '.cacheGeomPath', "|", type="string")  # root

        # Lock parenting of the transform and cache
        cmds.lockNode([transform, cache], lock=True)

        nodes = [root, transform, cache]
        self[:] = nodes

        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
Example #12
0
    def launch(self, session, event):
        # load shell scripts presets
        presets = config.get_presets()['ftrack'].get("user_assigment_event")
        if not presets:
            return
        for entity in event.get('data', {}).get('entities', []):
            if entity.get('entity_type') != 'Appointment':
                continue

            task, user = self._get_task_and_user(session,
                                                 entity.get('action'),
                                                 entity.get('changes'))

            if not task or not user:
                self.log.error(
                    'Task or User was not found.')
                continue

            data = self._get_template_data(task)
            # format directories to pass to shell script
            anatomy = Anatomy(data["project"]["name"])
            anatomy_filled = anatomy.format(data)
            # formatting work dir is easiest part as we can use whole path
            work_dir = anatomy_filled["work"]["folder"]
            # we also need publish but not whole
            anatomy_filled.strict = False
            publish = anatomy_filled["publish"]["folder"]

            # now find path to {asset}
            m = re.search("(^.+?{})".format(data['asset']),
                          publish)

            if not m:
                msg = 'Cannot get part of publish path {}'.format(publish)
                self.log.error(msg)
                return {
                    'success': False,
                    'message': msg
                }
            publish_dir = m.group(1)

            for script in presets.get(entity.get('action')):
                self.log.info(
                    '[{}] : running script for user {}'.format(
                        entity.get('action'), user["username"]))
                self._run_script(script, [user["username"],
                                          work_dir, publish_dir])

        return True
Example #13
0
def add_review_presets_config():
    returning = {
        "families": list(),
        "representations": list()
    }
    review_presets = config.get_presets()["plugins"]["global"]["publish"].get(
        "ExtractReview", {})

    outputs = review_presets.get("outputs", {})
    #
    for output, properities in outputs.items():
        returning["representations"].append(output)
        returning["families"] += properities.get("families", [])

    return returning
Example #14
0
    def __init__(self, session, plugins_presets):
        """ Constructor

            :param session: ftrack Session
            :type session: :class:`ftrack_api.Session`
        """
        super().__init__(session, plugins_presets)
        self.rv_path = None
        self.config_data = None

        # RV_HOME should be set if properly installed
        if os.environ.get('RV_HOME'):
            self.rv_path = os.path.join(os.environ.get('RV_HOME'), 'bin', 'rv')
        else:
            # if not, fallback to config file location
            if "rv" in config.get_presets():
                self.config_data = config.get_presets()['rv']['config']
                self.set_rv_path()

        if self.rv_path is None:
            return

        self.allowed_types = self.config_data.get('file_ext',
                                                  ["img", "mov", "exr"])
Example #15
0
    def reset(self):
        self.clear()
        self._item_count = 0
        self.default_index = 0

        intents_preset = (config.get_presets().get("tools", {}).get(
            "pyblish", {}).get("ui", {}).get("intents", {}))
        default = intents_preset.get("default")
        items = intents_preset.get("items", {})
        if not items:
            return

        for idx, item_value in enumerate(items.keys()):
            if item_value == default:
                self.default_index = idx
                break

        self.add_items(items)
Example #16
0
    def load(self, context, name, namespace, data):

        from avalon.maya.pipeline import containerise
        from pype.hosts.maya.lib import namespaced

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "vrayscene_layer"

        asset_name = context['asset']["name"]
        namespace = namespace or lib.unique_namespace(
            asset_name + "_",
            prefix="_" if asset_name[0].isdigit() else "",
            suffix="_",
        )

        # Ensure V-Ray for Maya is loaded.
        cmds.loadPlugin("vrayformaya", quiet=True)

        with lib.maintained_selection():
            cmds.namespace(addNamespace=namespace)
            with namespaced(namespace, new=False):
                nodes, group_node = self.create_vray_scene(name,
                                                           filename=self.fname)

        self[:] = nodes
        if not nodes:
            return

        # colour the group node
        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']
        c = colors.get(family)
        if c is not None:
            cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1)
            cmds.setAttr("{0}.outlinerColor".format(group_node), c[0], c[1],
                         c[2])

        return containerise(name=name,
                            namespace=namespace,
                            nodes=nodes,
                            context=context,
                            loader=self.__class__.__name__)
Example #17
0
    def __init__(self):
        self.qaction = None
        self.failed_icon = None
        self._is_running = False

        try:
            self.presets = config.get_presets()["services"]["rest_api"]
        except Exception:
            self.presets = {"default_port": 8011, "exclude_ports": []}
            log.debug(("There are not set presets for RestApiModule."
                       " Using defaults \"{}\"").format(str(self.presets)))

        port = self.find_port()
        self.rest_api_thread = RestApiThread(self, port)

        statics_dir = os.path.sep.join([os.environ["PYPE_MODULE_ROOT"], "res"])
        self.register_statics("/res", statics_dir)
        os.environ["PYPE_STATICS_SERVER"] = "{}/res".format(
            os.environ["PYPE_REST_API_URL"])
Example #18
0
def register(session, plugins_presets={}):
    app_usages = (config.get_presets().get("global",
                                           {}).get("applications")) or {}

    apps = []
    missing_app_names = []
    launchers_path = os.path.join(os.environ["PYPE_CONFIG"], "launchers")
    for file in os.listdir(launchers_path):
        filename, ext = os.path.splitext(file)
        if ext.lower() != ".toml":
            continue

        app_usage = app_usages.get(filename)
        if not app_usage:
            if app_usage is None:
                missing_app_names.append(filename)
            continue

        loaded_data = toml.load(os.path.join(launchers_path, file))
        app_data = {
            "name": filename,
            "label": loaded_data.get("label", filename)
        }
        apps.append(app_data)

    if missing_app_names:
        log.debug("Apps not defined in applications usage. ({})".format(
            ", ".join(("\"{}\"".format(app_name)
                       for app_name in missing_app_names))))

    apps = sorted(apps, key=lambda app: app["name"])
    app_counter = 0
    for app in apps:
        try:
            registerApp(app, session, plugins_presets)
            if app_counter % 5 == 0:
                time.sleep(0.1)
            app_counter += 1
        except Exception as exc:
            log.warning("\"{}\" - not a proper App ({})".format(
                app['name'], str(exc)),
                        exc_info=True)
Example #19
0
    def on_start(self):
        project_name = io.Session['AVALON_PROJECT']
        project_query = 'Project where full_name is "{}"'.format(project_name)
        if self.session is None:
            session = ftrack_api.Session()
            self.session = session
        else:
            session = self.session
        ft_project = session.query(project_query).one()
        schema_name = ft_project['project_schema']['name']
        # Load config
        schemas_items = config.get_presets().get('ftrack', {}).get(
            'project_schemas', {})
        # Get info if it is silo project
        self.silos = io.distinct("silo")
        if self.silos and None in self.silos:
            self.silos = None

        key = "default"
        if schema_name in schemas_items:
            key = schema_name

        self.config_data = schemas_items[key]

        # set outlink
        input_outlink = self.data['inputs']['outlink']
        checkbox_outlink = self.data['inputs']['outlink_cb']
        outlink_text = io.Session.get('AVALON_ASSET', '')
        checkbox_outlink.setChecked(True)
        if outlink_text == '':
            outlink_text = '< No context >'
            checkbox_outlink.setChecked(False)
            checkbox_outlink.hide()
        input_outlink.setText(outlink_text)

        # load asset build types
        self.load_assetbuild_types()

        # Load task templates
        self.load_task_templates()
        self.data["model"]["assets"].refresh()
        self.on_asset_changed()
Example #20
0
def _get_template_id(renderer):
    """
    Return muster template ID based on renderer name.

    :param renderer: renderer name
    :type renderer: str
    :returns: muster template id
    :rtype: int
    """

    templates = config.get_presets()["muster"]["templates_mapping"]
    if not templates:
        raise RuntimeError(("Muster template mapping missing in pype-config "
                            "`presets/muster/templates_mapping.json`"))
    try:
        template_id = templates[renderer]
    except KeyError:
        raise RuntimeError("Unmapped renderer - missing template id")

    return template_id
Example #21
0
    def process(self, context):
        presets = config.get_presets()
        try:
            # try if it is not in projects custom directory
            # `{PYPE_PROJECT_CONFIGS}/[PROJECT_NAME]/init.json`
            # init.json define preset names to be used
            p_init = presets["init"]
            presets["colorspace"] = presets["colorspace"][p_init["colorspace"]]
            presets["dataflow"] = presets["dataflow"][p_init["dataflow"]]
        except KeyError:
            self.log.warning("No projects custom preset available...")
            presets["colorspace"] = presets["colorspace"]["default"]
            presets["dataflow"] = presets["dataflow"]["default"]
            self.log.info(
                "Presets `colorspace` and `dataflow` loaded from `default`..."
            )

        context.data["presets"] = presets

        # self.log.info(context.data["presets"])
        return
Example #22
0
    def presets_by_hosts(self):
        # Get global filters as base
        presets = config.get_presets().get("plugins", {})
        if not presets:
            return {}

        result = presets.get("global", {}).get("filter", {})
        hosts = pyblish.api.registered_hosts()
        for host in hosts:
            host_presets = presets.get(host, {}).get("filter")
            if not host_presets:
                continue

            for key, value in host_presets.items():
                if value is None:
                    if key in result:
                        result.pop(key)
                    continue

                result[key] = value

        return result
Example #23
0
    def __init__(self, parent):
        super().__init__()
        self.parent_widget = parent
        self.presets = config.get_presets()['standalone_publish']

        self.setAcceptDrops(True)
        layout = QtWidgets.QVBoxLayout(self)
        self.components_list = ComponentsList(self)
        layout.addWidget(self.components_list)

        self.drop_widget = DropEmpty(self)

        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.drop_widget.sizePolicy().hasHeightForWidth())
        self.drop_widget.setSizePolicy(sizePolicy)

        layout.addWidget(self.drop_widget)

        self._refresh_view()
    def launch(self, session, entities, event):
        entity = entities[0]
        project = self.get_project_from_entity(entity)
        project_folder_presets = (config.get_presets().get(
            "tools", {}).get("project_folder_structure"))
        if not project_folder_presets:
            return {
                "success": False,
                "message": "Project structure presets are not set."
            }

        try:
            # Get paths based on presets
            basic_paths = self.get_path_items(project_folder_presets)
            anatomy = Anatomy(project["full_name"])
            self.create_folders(basic_paths, entity, project, anatomy)
            self.create_ftrack_entities(basic_paths, project)

        except Exception as exc:
            session.rollback()
            return {"success": False, "message": str(exc)}

        return True
Example #25
0
def burnins_from_data(
    input_path, output_path, data,
    codec_data=None, options=None, burnin_values=None, overwrite=True
):
    """This method adds burnins to video/image file based on presets setting.

    Extension of output MUST be same as input. (mov -> mov, avi -> avi,...)

    Args:
        input_path (str): Full path to input file where burnins should be add.
        output_path (str): Full path to output file where output will be
            rendered.
        data (dict): Data required for burnin settings (more info below).
        codec_data (list): All codec related arguments in list.
        options (dict): Options for burnins.
        burnin_values (dict): Contain positioned values.
        overwrite (bool): Output will be overriden if already exists,
            True by default.

    Presets must be set separately. Should be dict with 2 keys:
    - "options" - sets look of burnins - colors, opacity,...(more info: ModifiedBurnins doc)
                - *OPTIONAL* default values are used when not included
    - "burnins" - contains dictionary with burnins settings
                - *OPTIONAL* burnins won't be added (easier is not to use this)
        - each key of "burnins" represents Alignment, there are 6 possibilities:
            TOP_LEFT        TOP_CENTERED        TOP_RIGHT
            BOTTOM_LEFT     BOTTOM_CENTERED     BOTTOM_RIGHT
        - value must be string with text you want to burn-in
        - text may contain specific formatting keys (exmplained below)

    Requirement of *data* keys is based on presets.
    - "frame_start" - is required when "timecode" or "current_frame" ins keys
    - "frame_start_tc" - when "timecode" should start with different frame
    - *keys for static text*

    EXAMPLE:
    preset = {
        "options": {*OPTIONS FOR LOOK*},
        "burnins": {
            "TOP_LEFT": "static_text",
            "TOP_RIGHT": "{shot}",
            "BOTTOM_LEFT": "TC: {timecode}",
            "BOTTOM_RIGHT": "{frame_start}{current_frame}"
        }
    }

    For this preset we'll need at least this data:
    data = {
        "frame_start": 1001,
        "shot": "sh0010"
    }

    When Timecode should start from 1 then data need:
    data = {
        "frame_start": 1001,
        "frame_start_tc": 1,
        "shot": "sh0010"
    }
    """

    # Use legacy processing when options are not set
    if options is None or burnin_values is None:
        presets = config.get_presets().get("tools", {}).get("burnins", {})
        options = presets.get("options")
        burnin_values = presets.get("burnins") or {}

    burnin = ModifiedBurnins(input_path, options_init=options)

    frame_start = data.get("frame_start")
    frame_end = data.get("frame_end")
    frame_start_tc = data.get('frame_start_tc', frame_start)

    stream = burnin._streams[0]
    if "resolution_width" not in data:
        data["resolution_width"] = stream.get("width", MISSING_KEY_VALUE)

    if "resolution_height" not in data:
        data["resolution_height"] = stream.get("height", MISSING_KEY_VALUE)

    if "fps" not in data:
        data["fps"] = get_fps(stream.get("r_frame_rate", "0/0"))

    # Check frame start and add expression if is available
    if frame_start is not None:
        data[CURRENT_FRAME_KEY[1:-1]] = CURRENT_FRAME_SPLITTER

    if frame_start_tc is not None:
        data[TIMECODE_KEY[1:-1]] = TIMECODE_KEY

    source_timecode = stream.get("timecode")
    if source_timecode is None:
        source_timecode = stream.get("tags", {}).get("timecode")

    if source_timecode is not None:
        data[SOURCE_TIMECODE_KEY[1:-1]] = SOURCE_TIMECODE_KEY

    for align_text, value in burnin_values.items():
        if not value:
            continue

        if isinstance(value, (dict, list, tuple)):
            raise TypeError((
                "Expected string or number type."
                " Got: {} - \"{}\""
                " (Make sure you have new burnin presets)."
            ).format(str(type(value)), str(value)))

        align = None
        align_text = align_text.strip().lower()
        if align_text == "top_left":
            align = ModifiedBurnins.TOP_LEFT
        elif align_text == "top_centered":
            align = ModifiedBurnins.TOP_CENTERED
        elif align_text == "top_right":
            align = ModifiedBurnins.TOP_RIGHT
        elif align_text == "bottom_left":
            align = ModifiedBurnins.BOTTOM_LEFT
        elif align_text == "bottom_centered":
            align = ModifiedBurnins.BOTTOM_CENTERED
        elif align_text == "bottom_right":
            align = ModifiedBurnins.BOTTOM_RIGHT

        has_timecode = TIMECODE_KEY in value
        # Replace with missing key value if frame_start_tc is not set
        if frame_start_tc is None and has_timecode:
            has_timecode = False
            log.warning(
                "`frame_start` and `frame_start_tc`"
                " are not set in entered data."
            )
            value = value.replace(TIMECODE_KEY, MISSING_KEY_VALUE)

        has_source_timecode = SOURCE_TIMECODE_KEY in value
        if source_timecode is None and has_source_timecode:
            has_source_timecode = False
            log.warning("Source does not have set timecode value.")
            value = value.replace(SOURCE_TIMECODE_KEY, MISSING_KEY_VALUE)

        key_pattern = re.compile(r"(\{.*?[^{0]*\})")

        missing_keys = []
        for group in key_pattern.findall(value):
            try:
                group.format(**data)
            except (TypeError, KeyError):
                missing_keys.append(group)

        missing_keys = list(set(missing_keys))
        for key in missing_keys:
            value = value.replace(key, MISSING_KEY_VALUE)

        # Handle timecode differently
        if has_source_timecode:
            args = [align, frame_start, frame_end, source_timecode]
            if not value.startswith(SOURCE_TIMECODE_KEY):
                value_items = value.split(SOURCE_TIMECODE_KEY)
                text = value_items[0].format(**data)
                args.append(text)

            burnin.add_timecode(*args)
            continue

        if has_timecode:
            args = [align, frame_start, frame_end, frame_start_tc]
            if not value.startswith(TIMECODE_KEY):
                value_items = value.split(TIMECODE_KEY)
                text = value_items[0].format(**data)
                args.append(text)

            burnin.add_timecode(*args)
            continue

        text = value.format(**data)
        burnin.add_text(text, align, frame_start, frame_end)

    ffmpeg_args = []
    if codec_data:
        # Use codec definition from method arguments
        ffmpeg_args = codec_data

    else:
        codec_name = burnin._streams[0].get("codec_name")
        if codec_name:
            ffmpeg_args.append("-codec:v {}".format(codec_name))

        profile_name = burnin._streams[0].get("profile")
        if profile_name:
            # lower profile name and repalce spaces with underscore
            profile_name = profile_name.replace(" ", "_").lower()
            ffmpeg_args.append("-profile:v {}".format(profile_name))

        pix_fmt = burnin._streams[0].get("pix_fmt")
        if pix_fmt:
            ffmpeg_args.append("-pix_fmt {}".format(pix_fmt))

    ffmpeg_args_str = " ".join(ffmpeg_args)
    burnin.render(
        output_path, args=ffmpeg_args_str, overwrite=overwrite, **data
    )
Example #26
0
host_ip = socket.gethostbyname(socket.gethostname())
action_data = {
    "label":
    "Pype Admin",
    "variant":
    "- Event server Status ({})".format(host_ip),
    "description":
    "Get Infromation about event server",
    "actionIdentifier":
    action_identifier,
    "icon":
    "{}/ftrack/action_icons/PypeAdmin.svg".format(
        os.environ.get(
            "PYPE_STATICS_SERVER",
            "http://localhost:{}".format(config.get_presets().get(
                "services", {}).get("rest_api", {}).get("default_port",
                                                        8021))))
}


class ObjectFactory:
    session = None
    status_factory = None
    checker_thread = None
    last_trigger = None


class Status:
    default_item = {
        "type": "label",
        "value": "Process info is not available at this moment."
Example #27
0
    def process_reference(self, context, name, namespace, options):
        import maya.cmds as cmds
        from avalon import maya
        import pymel.core as pm

        try:
            family = context["representation"]["context"]["family"]
        except ValueError:
            family = "model"

        with maya.maintained_selection():

            groupName = "{}:{}".format(namespace, name)
            cmds.loadPlugin("AbcImport.mll", quiet=True)
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              sharedReferenceFile=False,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name),
                              reference=True,
                              returnNewNodes=True)

            # namespace = cmds.referenceQuery(nodes[0], namespace=True)

            shapes = cmds.ls(nodes, shapes=True, long=True)

            newNodes = (list(set(nodes) - set(shapes)))

            current_namespace = pm.namespaceInfo(currentNamespace=True)

            if current_namespace != ":":
                groupName = current_namespace + ":" + groupName

            groupNode = pm.PyNode(groupName)
            roots = set()

            for node in newNodes:
                try:
                    roots.add(pm.PyNode(node).getAllParents()[-2])
                except:  # noqa: E722
                    pass

            if family not in ["layout", "setdress", "mayaAscii"]:
                for root in roots:
                    root.setParent(world=True)

            groupNode.zeroTransformPivots()
            for root in roots:
                root.setParent(groupNode)

            cmds.setAttr(groupName + ".displayHandle", 1)

            presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
            colors = presets['plugins']['maya']['load']['colors']
            c = colors.get(family)
            if c is not None:
                groupNode.useOutlinerColor.set(1)
                groupNode.outlinerColor.set(c[0], c[1], c[2])

            self[:] = newNodes

            cmds.setAttr(groupName + ".displayHandle", 1)
            # get bounding box
            bbox = cmds.exactWorldBoundingBox(groupName)
            # get pivot position on world space
            pivot = cmds.xform(groupName, q=True, sp=True, ws=True)
            # center of bounding box
            cx = (bbox[0] + bbox[3]) / 2
            cy = (bbox[1] + bbox[4]) / 2
            cz = (bbox[2] + bbox[5]) / 2
            # add pivot position to calculate offset
            cx = cx + pivot[0]
            cy = cy + pivot[1]
            cz = cz + pivot[2]
            # set selection handle offset to center of bounding box
            cmds.setAttr(groupName + ".selectHandleX", cx)
            cmds.setAttr(groupName + ".selectHandleY", cy)
            cmds.setAttr(groupName + ".selectHandleZ", cz)

            if family == "rig":
                self._post_process_rig(name, namespace, context, options)
            else:
                if "translate" in options:
                    cmds.setAttr(groupName + ".t", *options["translate"])

            return newNodes
Example #28
0
    def process_reference(self,
                          context,
                          name=None,
                          namespace=None,
                          options=None):

        import maya.cmds as cmds
        from avalon import maya

        # get roots of selected hierarchies
        selected_roots = []
        for sel in cmds.ls(sl=True, long=True):
            selected_roots.append(sel.split("|")[1])

        # get all objects under those roots
        selected_hierarchy = []
        for root in selected_roots:
            selected_hierarchy.append(
                cmds.listRelatives(root, allDescendents=True) or [])

        # flatten the list and filter only shapes
        shapes_flat = []
        for root in selected_hierarchy:
            shapes = cmds.ls(root, long=True, type="mesh") or []
            for shape in shapes:
                shapes_flat.append(shape)

        # create dictionary of cbId and shape nodes
        scene_lookup = defaultdict(list)
        for node in shapes_flat:
            cb_id = lib.get_id(node)
            scene_lookup[cb_id] = node

        # load rig
        with maya.maintained_selection():
            nodes = cmds.file(self.fname,
                              namespace=namespace,
                              reference=True,
                              returnNewNodes=True,
                              groupReference=True,
                              groupName="{}:{}".format(namespace, name))

        # for every shape node we've just loaded find matching shape by its
        # cbId in selection. If found outMesh of scene shape will connect to
        # inMesh of loaded shape.
        for destination_node in nodes:
            source_node = scene_lookup[lib.get_id(destination_node)]
            if source_node:
                self.log.info("found: {}".format(source_node))
                self.log.info(
                    "creating connection to {}".format(destination_node))

                cmds.connectAttr("{}.outMesh".format(source_node),
                                 "{}.inMesh".format(destination_node),
                                 force=True)

        groupName = "{}:{}".format(namespace, name)

        presets = config.get_presets(project=os.environ['AVALON_PROJECT'])
        colors = presets['plugins']['maya']['load']['colors']

        c = colors.get('yetiRig')
        if c is not None:
            cmds.setAttr(groupName + ".useOutlinerColor", 1)
            cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2])
        self[:] = nodes

        return nodes
Example #29
0
    def load(self, context, name, namespace, data):
        self.djv_path = None
        paths = config.get_presets().get("djv_view",
                                         {}).get("config",
                                                 {}).get("djv_paths", [])
        for path in paths:
            if os.path.exists(path):
                self.djv_path = path
                break
        directory = os.path.dirname(self.fname)
        from avalon.vendor import clique

        pattern = clique.PATTERNS["frames"]
        files = os.listdir(directory)
        collections, remainder = clique.assemble(files,
                                                 patterns=[pattern],
                                                 minimum_items=1)

        if not remainder:
            seqeunce = collections[0]
            first_image = list(seqeunce)[0]
            # start = min(collections)
            # end = max(collections)
            #
            # range = (padding % start) + '-' + (padding % end)
            # filename = re.sub('%[0-9]*d', range, filename)
        else:
            first_image = self.fname
        filepath = os.path.normpath(os.path.join(directory, first_image))

        self.log.info("Opening : {}".format(filepath))

        fps = context.get('project', {}).get('data', {}).get('fps', 24)

        cmd = []
        # DJV path
        cmd.append(os.path.normpath(self.djv_path))
        # DJV Options Start ##############################################
        '''layer name'''
        # cmd.append('-file_layer (value)')
        ''' Proxy scale: 1/2, 1/4, 1/8'''
        # cmd.append('-file_proxy 1/2')
        ''' Cache: True, False.'''
        cmd.append('-file_cache True')
        ''' Start in full screen '''
        # cmd.append('-window_fullscreen')
        ''' Toolbar controls: False, True.'''
        # cmd.append("-window_toolbar False")
        ''' Window controls: False, True.'''
        # cmd.append("-window_playbar False")
        ''' Grid overlay: None, 1x1, 10x10, 100x100.'''
        # cmd.append("-view_grid None")
        ''' Heads up display: True, False.'''
        # cmd.append("-view_hud True")
        ''' Playback: Stop, Forward, Reverse.'''
        cmd.append("-playback Forward")
        ''' Frame.'''
        # cmd.append("-playback_frame (value)")
        cmd.append("-playback_speed " + str(fps))
        ''' Timer: Sleep, Timeout. Value: Sleep.'''
        # cmd.append("-playback_timer (value)")
        ''' Timer resolution (seconds): 0.001.'''
        # cmd.append("-playback_timer_resolution (value)")
        ''' Time units: Timecode, Frames.'''
        cmd.append("-time_units Frames")
        # DJV Options End ################################################

        # PATH TO COMPONENT
        cmd.append(os.path.normpath(filepath))

        # Run DJV with these commands
        subprocess.Popen(' '.join(cmd))
Example #30
0
def get_representation():
    return config.get_presets().get("djv_view",
                                    {}).get("config", {}).get('file_ext', [])