コード例 #1
0
ファイル: source.py プロジェクト: chippey/dpa-pipe
    def validate(self):

        # current ptask/version
        try:
            area = PTaskArea.current()
            self._current_ptask = PTask.get(area.spec)
            self._current_ptask_version = self._current_ptask.latest_version
        except PTaskError:
            raise ActionError("Unable to find ptask: " + str(self._ptask))

        # source ptask
        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Unable to find ptask: " + str(self._ptask))

        # source ptask version
        if isinstance(self._version, PTaskVersion):
            pass
        elif self._version:
            matches = PTaskVersion.list(
                ptask=self._ptask.spec, number=self._version
            )
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find ptask '{p}' at version '{v}'".format(
                        p=self._ptask.spec, v=self._version
                    )
                )
            else:
                self._version = matches[0]
        else:
            self._version = self._ptask.latest_version

        # source subs
        self._match_str = self._match_str.replace("%", ".*")

        all_subs = self._version.subscriptions
        self._subs_to_source = []
        for sub in all_subs:
            if re.search(self._match_str, sub.product_version_spec):
                self._subs_to_source.append(sub)

        if not self._subs_to_source:
            raise ActionAborted("No subscriptions to source.")
コード例 #2
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def _create_ptask(self):

        parent = PTaskSpec.parent(self.spec)
        name = PTaskSpec.name(self.spec)

        # create
        if not self.ptask:
            try:
                self.logger.debug("Creating ptask: " + str(self.spec))
                self._ptask = PTask.create(
                    name,
                    self.ptask_type,
                    self.description,
                    creator_username=self.creator,
                    parent_spec=parent,
                    start_date=str(self.start_date),
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to create ptask: " + str(e))
        # update
        else:
            try:
                self.logger.debug("Updating ptask: " + str(self.spec))
                self.ptask.update(
                    description=self.description,
                    start_date=str(self.start_date),
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to update ptask: " + str(e))
コード例 #3
0
ファイル: create.py プロジェクト: chippey/dpa-pipe
    def _create_ptask(self):

        parent = PTaskSpec.parent(self.spec)
        name = PTaskSpec.name(self.spec)

        # create
        if not self.ptask:
            try:
                self.logger.debug("Creating ptask: " + str(self.spec))
                self._ptask = PTask.create(
                    name, 
                    self.ptask_type,
                    self.description, 
                    creator_username=self.creator, 
                    parent_spec=parent, 
                    start_date=str(self.start_date), 
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to create ptask: " + str(e)) 
        # update
        else:
            try:
                self.logger.debug("Updating ptask: " + str(self.spec))
                self.ptask.update(
                    description=self.description, 
                    start_date=str(self.start_date), 
                    due_date=str(self.due_date),
                )
            except PTaskError as e:
                raise ActionError("Failed to update ptask: " + str(e)) 
コード例 #4
0
ファイル: list.py プロジェクト: chippey/dpa-pipe
    def validate(self):

        cur_spec = PTaskArea.current().spec
        full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec)

        # if we're listing the current ptask's subs, and no versions specified
        if cur_spec == full_spec and not self._versions:
            ptask_ver = DpaVars.ptask_version().get()
            if ptask_ver:
                self._versions = [ptask_ver]

        if not self._versions:
            self._versions = ["latest"]

        # try to get a ptask instance from the db
        try:
            ptask = PTask.get(full_spec)
        except PTaskError as e:
            # fall back to the input spec
            try:
                ptask = PTask.get(self.spec)
            except PTaskError:
                raise ActionError(
                    'Could not determine ptask from: "{s}"'.format(
                        s=self.spec)
                )

        self._ptask = ptask

        if self._versions == ['latest']:
            versions = [self.ptask.latest_version]
        elif self._versions == ['all']:
            versions = self.ptask.versions
        else:
            self._versions = map(int, self._versions)
            versions = [v for v in self.ptask.versions 
                if v.number in self._versions]

        if len(versions) == 0:
            raise ActionError(
                "No matches found for {p} version: {v}".format(
                    p=ptask.spec,
                    v=Style.bright + str(self._versions) + Style.normal,
                )
            )

        self._versions = versions
コード例 #5
0
ファイル: __init__.py プロジェクト: chippey/dpa-pipe
    def ptask(self):
        """:returns: PTask object for this version."""
        if not self.ptask_spec:
            return None 

        # import here to avoid circular dependencies
        from dpa.ptask import PTask
        return PTask.get(self.ptask_spec)
コード例 #6
0
    def ptask(self):
        """:returns: PTask object for this assignment."""
        if not self.ptask_spec:
            return None

        # import here to avoid circular dependencies
        from dpa.ptask import PTask
        return PTask.get(self.ptask_spec)
コード例 #7
0
ファイル: source.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        # current ptask/version
        try:
            area = PTaskArea.current()
            self._current_ptask = PTask.get(area.spec)
            self._current_ptask_version = self._current_ptask.latest_version
        except PTaskError:
            raise ActionError("Unable to find ptask: " + str(self._ptask))

        # source ptask
        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Unable to find ptask: " + str(self._ptask))

        # source ptask version
        if isinstance(self._version, PTaskVersion):
            pass
        elif self._version:
            matches = PTaskVersion.list(ptask=self._ptask.spec,
                                        number=self._version)
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find ptask '{p}' at version '{v}'".format(
                        p=self._ptask.spec, v=self._version))
            else:
                self._version = matches[0]
        else:
            self._version = self._ptask.latest_version

        # source subs
        self._match_str = self._match_str.replace("%", ".*")

        all_subs = self._version.subscriptions
        self._subs_to_source = []
        for sub in all_subs:
            if re.search(self._match_str, sub.product_version_spec):
                self._subs_to_source.append(sub)

        if not self._subs_to_source:
            raise ActionAborted("No subscriptions to source.")
コード例 #8
0
    def validate(self):

        cur_spec = PTaskArea.current().spec
        full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec)

        # if we're listing the current ptask's subs, and no versions specified
        if cur_spec == full_spec and not self._versions:
            ptask_ver = DpaVars.ptask_version().get()
            if ptask_ver:
                self._versions = [ptask_ver]

        if not self._versions:
            self._versions = ["latest"]

        # try to get a ptask instance from the db
        try:
            ptask = PTask.get(full_spec)
        except PTaskError as e:
            # fall back to the input spec
            try:
                ptask = PTask.get(self.spec)
            except PTaskError:
                raise ActionError(
                    'Could not determine ptask from: "{s}"'.format(
                        s=self.spec))

        self._ptask = ptask

        if self._versions == ['latest']:
            versions = [self.ptask.latest_version]
        elif self._versions == ['all']:
            versions = self.ptask.versions
        else:
            self._versions = map(int, self._versions)
            versions = [
                v for v in self.ptask.versions if v.number in self._versions
            ]

        if len(versions) == 0:
            raise ActionError("No matches found for {p} version: {v}".format(
                p=ptask.spec,
                v=Style.bright + str(self._versions) + Style.normal,
            ))

        self._versions = versions
コード例 #9
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def __init__(self,
                 spec,
                 ptask_type=None,
                 description=None,
                 creator=None,
                 start_date=None,
                 due_date=None,
                 source=None,
                 force=True):
        super(PTaskCreateAction, self).__init__(
            spec,
            ptask_type=ptask_type,
            description=description,
            creator=creator,
            start_date=start_date,
            due_date=due_date,
            source=source,
            force=force,
        )

        # allow calling code to override the target to specify the ptask type
        # to create
        if ptask_type is None:
            if self.__class__.target_type is not 'ptask':
                ptask_type = self.__class__.target_type
            else:
                raise ActionError("PTask type is required.")

        # do some initial validation on the supplied spec
        parent = PTaskSpec.parent(spec)

        if parent != "":
            try:
                parent = PTask.get(parent)
            except PTaskError:
                raise ActionError("Parent ptask does not exist: " + parent)

        name = PTaskSpec.name(spec)
        try:
            name = validate_ptask_name(name)
        except PTaskError as e:
            raise ActionError("Invalid ptask name: " + str(e))

        # input
        self._spec = spec
        self._ptask_type = ptask_type
        self._description = description
        self._creator = creator
        self._start_date = start_date
        self._due_date = due_date
        self._source = source
        self._force = force

        # to create
        self._ptask = None
        self._ptask_area = None
        self._ptask_version = None
コード例 #10
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        if self.source:
            try:
                self._source = PTask.get(self.source)
            except PTaskError:
                raise ActionError(
                    "Unable to retrieve ptask from source argument: " + \
                        str(self.source),
                )
コード例 #11
0
ファイル: action.py プロジェクト: chippey/dpa-pipe
    def validate(self):

        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Could not determine ptask from: {p}".format(
                    p=self._ptask))
コード例 #12
0
ファイル: create.py プロジェクト: chippey/dpa-pipe
    def validate(self):

        if self.source:
            try:
                self._source = PTask.get(self.source)
            except PTaskError:
                raise ActionError(
                    "Unable to retrieve ptask from source argument: " + \
                        str(self.source),
                )
コード例 #13
0
    def validate(self):

        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Could not determine ptask from: {p}".format(
                    p=self._ptask))
コード例 #14
0
ファイル: info.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        cur_spec = PTaskArea.current().spec
        full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec)

        # try to get a ptask instance from the db
        if full_spec:
            try:
                ptask = PTask.get(full_spec)
            except PTaskError as e:
                # fall back to the input spec
                try:
                    ptask = PTask.get(self.spec)
                except PTaskError:
                    raise ActionError(
                        'Could not determine ptask from: "{s}"'.format(
                            s=self.spec))
        else:
            ptask = None

        self._ptask = ptask
コード例 #15
0
ファイル: info.py プロジェクト: chippey/dpa-pipe
    def validate(self):
        
        cur_spec = PTaskArea.current().spec
        full_spec = PTaskSpec.get(self.spec, relative_to=cur_spec)

        # try to get a ptask instance from the db
        if full_spec:
            try:
                ptask = PTask.get(full_spec)
            except PTaskError as e:
                # fall back to the input spec
                try:
                    ptask = PTask.get(self.spec)
                except PTaskError:
                    raise ActionError(
                        'Could not determine ptask from: "{s}"'.format(
                            s=self.spec)
                    )
        else:
            ptask = None

        self._ptask = ptask
コード例 #16
0
    def ptask(self):

        if not hasattr(self, '_ptask'):
            ptask_area = self.ptask_area
            if not ptask_area.spec:
                self._ptask = None
            else:
                try:
                    self._ptask = PTask.get(ptask_area.spec)
                except PTaskError as e:
                    raise SessionError("Unable to determine ptask.")

        return self._ptask
コード例 #17
0
ファイル: refresh.py プロジェクト: chippey/dpa-pipe
    def validate(self):
        
        use_cur_version = False

        if not isinstance(self.ptask, PTask):

            if not self.ptask or self.ptask == '.':
                use_cur_version = True

            cur_spec = PTaskArea.current().spec
            full_spec = PTaskSpec.get(self.ptask, relative_to=cur_spec)

            # try to get a ptask instance from the db
            try:
                ptask = PTask.get(full_spec)
            except PTaskError as e:
                # fall back to the input spec
                try:
                    ptask = PTask.get(self.spec)
                except PTaskError:
                    raise ActionError(
                        'Could not determine ptask from: "{s}"'.format(
                            s=self.spec)
                    )

            self._ptask = ptask

        latest_ver = self.ptask.latest_version

        if use_cur_version:
            cur_ptask_ver = DpaVars.ptask_version().get()
            if cur_ptask_ver and cur_ptask_ver != latest_ver.number:
                self._ptask_version = self.ptask.version(cur_ptask_ver)
                self._version = cur_ptask_ver
            else:
                self._ptask_version = self.ptask.latest_version
        else:
            self._ptask_version = self.ptask.latest_version
コード例 #18
0
ファイル: create.py プロジェクト: chippey/dpa-pipe
    def __init__(self, spec, ptask_type=None, description=None, creator=None,
        start_date=None, due_date=None, source=None, force=True):
        super(PTaskCreateAction, self).__init__(
            spec,
            ptask_type=ptask_type,
            description=description,
            creator=creator,
            start_date=start_date,
            due_date=due_date,
            source=source,
            force=force,
        )

        # allow calling code to override the target to specify the ptask type
        # to create
        if ptask_type is None:
            if self.__class__.target_type is not 'ptask':
                ptask_type = self.__class__.target_type
            else:
                raise ActionError("PTask type is required.")

        # do some initial validation on the supplied spec
        parent = PTaskSpec.parent(spec)

        if parent != "":
            try:
                parent = PTask.get(parent)
            except PTaskError:
                raise ActionError("Parent ptask does not exist: " + parent)

        name = PTaskSpec.name(spec)
        try:
            name = validate_ptask_name(name)
        except PTaskError as e:
            raise ActionError("Invalid ptask name: " + str(e))
        
        # input
        self._spec = spec
        self._ptask_type = ptask_type
        self._description = description
        self._creator = creator
        self._start_date = start_date
        self._due_date = due_date
        self._source = source
        self._force = force

        # to create
        self._ptask = None
        self._ptask_area = None
        self._ptask_version = None
コード例 #19
0
    def validate(self):

        use_cur_version = False

        if not isinstance(self.ptask, PTask):

            if not self.ptask or self.ptask == '.':
                use_cur_version = True

            cur_spec = PTaskArea.current().spec
            full_spec = PTaskSpec.get(self.ptask, relative_to=cur_spec)

            # try to get a ptask instance from the db
            try:
                ptask = PTask.get(full_spec)
            except PTaskError as e:
                # fall back to the input spec
                try:
                    ptask = PTask.get(self.spec)
                except PTaskError:
                    raise ActionError(
                        'Could not determine ptask from: "{s}"'.format(
                            s=self.spec))

            self._ptask = ptask

        latest_ver = self.ptask.latest_version

        if use_cur_version:
            cur_ptask_ver = DpaVars.ptask_version().get()
            if cur_ptask_ver and cur_ptask_ver != latest_ver.number:
                self._ptask_version = self.ptask.version(cur_ptask_ver)
                self._version = cur_ptask_ver
            else:
                self._ptask_version = self.ptask.latest_version
        else:
            self._ptask_version = self.ptask.latest_version
コード例 #20
0
def populate_sub_cache(ptask_version=None, refresh=False):

    if not ptask_version:

        ptask_area = PTaskArea.current()
        ptask = PTask.get(ptask_area.spec)

        if ptask_area.version:
            ptask_version = ptask.version(ptask_area.version)
        else:
            ptask_version = ptask.latest_version

    nuke_file = nuke.root().name()
    nuke_dir = os.path.dirname(nuke_file)

    if refresh or not SUBD_REPR_CACHE:

        for sub in ptask_version.subscriptions:
            for product_repr in sub.product_version.representations:

                product = product_repr.product_version.product

                if product.category != 'imgseq':
                    continue

                product_repr_str = product.name_spec + ' @ ' + \
                    product_repr.type

                if product_repr.resolution != 'none':
                    product_repr_str += PTaskSpec.SEPARATOR + \
                    product_repr.resolution

                sub_import_dir = get_import_dir(product_repr,
                                                product=product,
                                                area=ptask_area,
                                                relative_to=nuke_dir)

                # populate cache lookups
                SUBD_REPR_CACHE.append(product_repr)
                PRODUCT_REPR_STR_TO_PATH[product_repr_str] = \
                    sub_import_dir
コード例 #21
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        if self.interactive:
            print "\nValidating product arguments ..."

        # should have a valid product name, 
        self._name = validate_product_name(self._name)

        if self._category:
            if not self._category in Product.category_names():
                raise ActionError("Unrecognized category.")
        else:
            raise ActionError("Category is required.")

        if not self._description:
            raise ActionError("Description is required.")

        # ptask
        if not isinstance(self._ptask, PTask):
            try:
                self._ptask = PTask.get(self._ptask)
            except PTaskError:
                raise ActionError("Could not determine ptask.")
                
        if self._version:
            self._ptask_version = self._ptask.version(self._version)
        else:
            self._ptask_version = self._ptask.latest_version

        if not self._ptask_version:
            raise ActionError("Could not determine ptask version.")

        if not self._note:
            self._note = "None"

        if self._path:
            if not os.path.exists(self._path):
                raise ActionError("Supplied path does not exist.")
            if (os.path.isdir(self._path) and 
                not self._path.endswith(os.path.sep)):
                self._path += os.path.sep
コード例 #22
0
    def validate(self):

        # make sure the ptask evaluates to a real ptask
        try:
            self._ptask = PTask.get(self.ptask)
        except PTaskError:
            raise ActionError("Unable to determine ptask from: " +
                              str(self.ptask))

        # for efficiency
        self._ptask_latest_version = self.ptask.latest_version

        # make sure the latest version is not this location
        if self.ptask_latest_version.location_code == current_location_code():
            raise ActionError(
                "Latest version of {b}{p}{r} already owned by this location.".\
                    format(
                        b=Style.bright,
                        p=self.ptask.spec,
                        r=Style.reset,
                    )
            )
コード例 #23
0
ファイル: nodes.py プロジェクト: chippey/dpa-pipe
def populate_sub_cache(ptask_version=None, refresh=False):

    if not ptask_version:

        ptask_area = PTaskArea.current()
        ptask = PTask.get(ptask_area.spec)

        if ptask_area.version:
            ptask_version = ptask.version(ptask_area.version)
        else:
            ptask_version = ptask.latest_version

    nuke_file = nuke.root().name()
    nuke_dir = os.path.dirname(nuke_file)

    if refresh or not SUBD_REPR_CACHE:

        for sub in ptask_version.subscriptions:
            for product_repr in sub.product_version.representations:

                product = product_repr.product_version.product

                if product.category != 'imgseq':
                    continue

                product_repr_str = product.name_spec + ' @ ' + \
                    product_repr.type

                if product_repr.resolution != 'none':
                    product_repr_str += PTaskSpec.SEPARATOR + \
                    product_repr.resolution 

                sub_import_dir = get_import_dir(product_repr,
                    product=product, area=ptask_area, relative_to=nuke_dir)

                # populate cache lookups
                SUBD_REPR_CACHE.append(product_repr)
                PRODUCT_REPR_STR_TO_PATH[product_repr_str] = \
                    sub_import_dir
コード例 #24
0
ファイル: sync.py プロジェクト: DarkRoseAM/dpa-pipe
    def validate(self):

        cur_loc_code = current_location_code()

        try:
            self._ptask = PTask.get(self.ptask)
        except PTaskError as e:
            raise ActionError(
                "Unable to determine ptask from spec: " + str(self.ptask)
            )

        # just sync the supplied version
        if self.version:
            try:
                ptask_version = _get_ptask_version(
                    self.ptask,
                    self.version,
                )
            except TypeError as e:
                raise ActionError("Unable to retrieve ptask version: " + str(e))

            # make sure we got a version and it's not this location
            if ptask_version is None:
                raise ActionError(
                    "No ptask version matching: " + str(self.version)
                )
            # make sure the location is not this location
            elif ptask_version.location_code == cur_loc_code:
                raise ActionError("Specified version exists in this location.")
                
            versions = [ptask_version]

        # sync all ptask versions that are not in this location
        else:
            versions = [v for v in self.ptask.versions 
                if v.location_code != cur_loc_code]

        self._versions = versions
コード例 #25
0
ファイル: sync.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        cur_loc_code = current_location_code()

        try:
            self._ptask = PTask.get(self.ptask)
        except PTaskError as e:
            raise ActionError(
                "Unable to determine ptask from spec: " + str(self.ptask)
            )

        # just sync the supplied version
        if self.version:
            try:
                ptask_version = _get_ptask_version(
                    self.ptask,
                    self.version,
                )
            except TypeError as e:
                raise ActionError("Unable to retrieve ptask version: " + str(e))

            # make sure we got a version and it's not this location
            if ptask_version is None:
                raise ActionError(
                    "No ptask version matching: " + str(self.version)
                )
            # make sure the location is not this location
            elif ptask_version.location_code == cur_loc_code:
                raise ActionError("Specified version exists in this location.")
                
            versions = [ptask_version]

        # sync all ptask versions that are not in this location
        else:
            versions = [v for v in self.ptask.versions 
                if v.location_code != cur_loc_code]

        self._versions = versions
コード例 #26
0
ファイル: version.py プロジェクト: chippey/dpa-pipe
    def __init__(self):

        self._ptask_area = PTaskArea.current()
        options_config = self._ptask_area.config(VERSION_OPTIONS_CONFIG,
            composite_ancestors=True)

        try:
            self._ptask = PTask.get(self._ptask_area.spec)
        except PTaskError as e:
            error_dialog = QtGui.QErrorMessage(self)
            error_dialog.setWindowTitle('Version Failure')
            error_dialog.showMessage("Unable to determine current ptask.")
            return

        icon_path = IconFactory().disk_path(VERSION_ICON_URI)

        super(PTaskVersionDialog, self).__init__(
            title='Version up',
            options_config=options_config,
            icon_path=icon_path,
            action_button_text='Submit',
            modal=False,
        )
コード例 #27
0
ファイル: transfer.py プロジェクト: chippey/dpa-pipe
    def validate(self):

        # make sure the ptask evaluates to a real ptask
        try:
            self._ptask = PTask.get(self.ptask)
        except PTaskError:
            raise ActionError(
                "Unable to determine ptask from: " + str(self.ptask)
            )

        # for efficiency
        self._ptask_latest_version = self.ptask.latest_version

        # make sure the latest version is not this location
        if self.ptask_latest_version.location_code == current_location_code():
            raise ActionError(
                "Latest version of {b}{p}{r} already owned by this location.".\
                    format(
                        b=Style.bright,
                        p=self.ptask.spec,
                        r=Style.reset,
                    )
            )
コード例 #28
0
ファイル: version.py プロジェクト: liudger/dpa-pipe
    def __init__(self):

        self._ptask_area = PTaskArea.current()
        options_config = self._ptask_area.config(VERSION_OPTIONS_CONFIG,
                                                 composite_ancestors=True)

        try:
            self._ptask = PTask.get(self._ptask_area.spec)
        except PTaskError as e:
            error_dialog = QtGui.QErrorMessage(self)
            error_dialog.setWindowTitle('Version Failure')
            error_dialog.showMessage("Unable to determine current ptask.")
            return

        icon_path = IconFactory().disk_path(VERSION_ICON_URI)

        super(PTaskVersionDialog, self).__init__(
            title='Version up',
            options_config=options_config,
            icon_path=icon_path,
            action_button_text='Submit',
            modal=False,
        )
コード例 #29
0
ファイル: version.py プロジェクト: liudger/dpa-pipe
    def validate(self):
        
        try:
            self._ptask = PTask.get(self.spec)
        except PTaskError:
            raise ActionError(
                "Unable to determine ptask from: " + str(self.spec)
            )

        self._latest_version = self.ptask.latest_version

        # determine the source version. also store a reference to the latest
        # version for efficiency
        if self.source_version:
            source_version = self.ptask.version(self.source_version)
            if source_version is None:
                raise ActionError(
                    "Could not determine source version from: " + \
                        self.source_version
                )
            self._source_version = source_version
        else:
            self._source_version = self.latest_version

        # latest version must exist in this location. 
        if self.latest_version.location_code != current_location_code():
            raise ActionError(
                "The latest version of this ptask is not owned by this " +
                "location.\nOwnership of this ptask must first be " + 
                "transferred to this location."
            )

        if self.source_version.ptask != self.ptask:
            raise ActionError(
                "Source version's ptask does not match the ptask being " + \
                "versioned."
            )
コード例 #30
0
ファイル: create.py プロジェクト: chippey/dpa-pipe
    def prompt(self):

        parent_spec = PTaskSpec.parent(self.spec)
        template_options = []

        if parent_spec:
            par_ptask = PTask.get(parent_spec)
            par_ptask_type = par_ptask.ptask_type
        else:
            par_ptask_type = 'none'

        ptask_area = PTaskArea(parent_spec, validate=False) 
        master_config = ptask_area.config(
            PROJECT_MASTER_CONFIG_PATH,
            composite_ancestors=True,
        )

        if not master_config or not hasattr(master_config, 'hierarchy'):
            raise ActionError("Unable to find project master config.")

        if not self.ptask_type in master_config.hierarchy[par_ptask_type]:
            raise ActionError(
                "Cannot create '{t}' ptask inside '{p}' ptask".format(
                    t=self.ptask_type,
                    p=par_ptask_type,
                )
            )

        # ---- prompt for missing fields 
        if not self.source and self.ptask_type in master_config.templates:
            for template_spec in master_config.templates[self.ptask_type]:
                trimmed_spec = re.sub(
                    "^templates?=", 
                    "", 
                    template_spec, 
                    flags=re.IGNORECASE
                )
                template_options.append(
                    (
                        re.sub("[=_-]+", " ", trimmed_spec).title(),
                        template_spec
                    )
                )

            self._source = Output.prompt_menu(
                "Select a template to source",
                prompt_str="Selection",
                options=template_options,
                help_str="Please choose from the templates listed.",
                none_option=True,
                custom_prompt="Custom Source",
                custom_blank=False
            )

        # see if the ptask already exists
        if not self.ptask:
            try:
                self._ptask = PTask.get(self.spec)
            except PTaskError:
                pass
            else:
                if not self.force:
                    raise ActionAborted("PTask already exists.")
                else:
                    if not self._description:
                        self._description = self.ptask.description
                    if not self._start_date:
                        self._start_date = self.ptask.start_date
                    if not self._due_date:
                        self._due_date = self.ptask.due_date

        if (not self.description or 
            not self.start_date or 
            not self.due_date):

            if self.force:
                raise ActionError(
                    "Cannot force creation without required fields."
                )
            else:
                print "\nPlease enter information about this new {b}{t}{r}:".\
                    format(
                        b=Style.bright,
                        t=self.ptask_type,
                        r=Style.reset,
                    )

        ptask_display = " [{pt}] {b}{s}{r}".format(
            pt=self.ptask_type,
            b=Style.bright,
            s=self.spec,
            r=Style.reset,
        )

        if not self.description:
            self._description = Output.prompt(
                '{pd} description'.format(pd=ptask_display),
                blank=False,
            )

        if not self.start_date:
            self._start_date = Output.prompt_date(
                '{pd} start date'.format(pd=ptask_display),
                blank=False,
            ) 
 
        if not self.due_date:
            self._due_date = Output.prompt_date(
                '{pd} due date'.format(pd=ptask_display),
                blank=False,
            )
コード例 #31
0
    def _output_options(self):

        output_type_lbl = QtGui.QLabel("Output:")
        output_type = QtGui.QComboBox()
        output_type.addItems(['Automatic', 'Manual'])

        header_layout = QtGui.QHBoxLayout()
        header_layout.addStretch()
        header_layout.addWidget(output_type_lbl)
        header_layout.addWidget(output_type)
        header_layout.addStretch()

        # ---- auto

        cur_area = PTaskArea.current()
        self._cur_ptask = PTask.get(cur_area.spec)
        if self._cur_ptask:
            self._version = \
                cur_area.version or self._cur_ptask.latest_version.number
        else:
            self._cur_ptask = None
            self._version = "None"

        ptask_lbl = QtGui.QLabel("PTask:")
        ptask_edit = QtGui.QLineEdit(str(self._cur_ptask))
        ptask_edit.setReadOnly(True)

        version_num = QtGui.QLabel("<B>v" + str(self._version) + "</B>")

        auto_layout = QtGui.QGridLayout()
        auto_layout.addWidget(ptask_lbl, 0, 0, QtCore.Qt.AlignRight)
        auto_layout.addWidget(ptask_edit, 0, 1)
        auto_layout.addWidget(version_num, 0, 2, QtCore.Qt.AlignLeft)
        auto_layout.setColumnStretch(0, 0)
        auto_layout.setColumnStretch(1, 1000)

        auto_widgets = QtGui.QWidget()
        auto_widgets.setLayout(auto_layout)

        # ---- manual

        dir_lbl = QtGui.QLabel("Directory:")
        self._dir_edit = QtGui.QLineEdit(os.getcwd())

        dir_btn = QtGui.QPushButton()
        dir_btn.setFlat(True)
        dir_btn_size = QtCore.QSize(22, 22)
        dir_btn.setFixedSize(dir_btn_size)
        dir_btn.setIcon(QtGui.QIcon(self.__class__._dir_path))
        dir_btn.setIconSize(dir_btn_size)

        dir_dialog = QtGui.QFileDialog(self, 'Output directory', 
            os.getcwd())
        dir_dialog.setFileMode(QtGui.QFileDialog.Directory)
        dir_dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True)
        dir_dialog.setOption(QtGui.QFileDialog.DontResolveSymlinks, True)
        dir_dialog.setOption(QtGui.QFileDialog.HideNameFilterDetails, True)
        dir_dialog.fileSelected.connect(self._dir_edit.setText)

        dir_btn.clicked.connect(dir_dialog.show)

        manual_layout = QtGui.QGridLayout()
        manual_layout.setContentsMargins(0, 0, 0, 0)
        manual_layout.addWidget(dir_lbl, 0, 0, QtCore.Qt.AlignRight)
        manual_layout.addWidget(self._dir_edit, 0, 1)
        manual_layout.addWidget(dir_btn, 0, 2)
        manual_layout.setColumnStretch(0, 0)
        manual_layout.setColumnStretch(1, 1000)
        manual_layout.setColumnStretch(2, 0)

        manual_widgets = QtGui.QWidget()
        manual_widgets.setLayout(manual_layout)

        self._output_stack = QtGui.QStackedWidget()
        self._output_stack.addWidget(auto_widgets)
        self._output_stack.addWidget(manual_widgets)

        output_type.activated.connect(self._output_stack.setCurrentIndex)

        # ---- layout

        output_layout = QtGui.QVBoxLayout()
        output_layout.addLayout(header_layout)
        output_layout.addWidget(self._output_stack)

        return output_layout 
コード例 #32
0
    def _render_to_product(self):

        # add the version note for the product
        render_node = self.session.nuke.toNode(self._node_to_render)
        render_node['product_ver_note'].setValue(self._version_note)

        # ---- progress dialog

        num_ops = 6
        cur_op = 0

        progress_dialog = QtGui.QProgressDialog(
            "Product render...", "", cur_op, num_ops, self)
        progress_dialog.setWindowTitle("Dark Knight is busy...")
        progress_dialog.setAutoReset(False)
        progress_dialog.setLabelText("Preparing nuke file for rendering...")
        progress_dialog.show()

        # ensure the product has been created
        progress_dialog.setLabelText("Creating product...")

        product_repr = create_product_before_render(node=render_node)
        product_repr_area = product_repr.area

        cur_op += 1
        progress_dialog.setValue(cur_op)

        # get timestamp for all the tasks being submitted
        now = datetime.datetime.now()

        ptask_area = PTaskArea.current()
        ptask = PTask.get(ptask_area.spec)

        if ptask_area.version:
            ptask_version = ptask.version(ptask_area.version)
        else:
            ptask_version = ptask.latest_version

        ptask_dir = ptask_area.dir()
        ver_dir = ptask_area.dir(version=ptask_version.number)

        nuke_file = self.session.nuke.root().name()
        nuke_file = nuke_file.replace(ptask_dir, ver_dir)

        file_base = os.path.splitext(os.path.split(nuke_file)[1])[0]

        # ---- sync current work area to version snapshot to render from

        progress_dialog.setLabelText("Sync'ing the latest work...")

        try:
            self.session.save() 
            self._sync_latest()
        except Exception as e:
            self._show_error("Unable to save & sync the latest work: " + str(e))
            self.setEnabled(True)
            progress_dialog.close()
            return

        cur_op += 1
        progress_dialog.setValue(cur_op)

        # make sure queue directory exists 

        progress_dialog.setLabelText("Provisioning the queue directory...")

        try:
            product_repr_area.provision('queue')
        except Exception as e:
            raise DarkKnightError(
                "Unable to create queue scripts directory: " + str(e))

        cur_op += 1
        progress_dialog.setValue(cur_op)

        queue_dir = product_repr_area.dir(dir_name='queue')
        tasks_info_file = os.path.join(queue_dir, 'tasks_info.cfg')
        tasks_info_config = Config()

        progress_dialog.setLabelText("Building the queue script...")

        # dpaset command to run
        dpaset_cmd = 'eval "`dpa env ptask {pt}@{vn}`"'.format(
            pt=ptask.spec, vn=ptask_version.number)

        frange_str = str(self._frange).replace("-", "_").replace(":", "_")

        script_path = os.path.join(queue_dir, 
            "{pn}.{fr}.sh".format(pn=render_node['product_name'].value(),
                fr=frange_str))

        render_cmd = "nuke --cont -f -F {fs}-{fe}x{step} -X {rn} -V 2 -x {nf}".\
            format(
                fs=self._frange.start,
                fe=self._frange.end,
                step=self._frange.step,
                rn=self._node_to_render,
                nf=nuke_file,
            )

        with open(script_path, "w") as script_file:
            script_file.write("#!/bin/bash\n\n")

            # XXX these should happen automatically in the queue...
            script_file.write("source /DPA/wookie/dpa/bash/startup.bash\n")
            script_file.write("pipeup\n\n")

            script_file.write("# set the ptask version to render\n")
            script_file.write(dpaset_cmd + "\n\n")

            script_file.write("# render!\n")
            script_file.write(render_cmd + "\n\n")

        os.chmod(script_path, 0770)

        cur_op += 1
        progress_dialog.setValue(cur_op)
            
        task_id = get_unique_id(product_repr_area.spec, dt=now)
        task_id += "_" + frange_str

        tasks_info_config.add('task_id', task_id)

        out_file = self.session.nuke.filename(render_node, 
            self.session.nuke.REPLACE)

        if not self._debug_mode:

            progress_dialog.setLabelText("Submitting to the queue...")

            create_queue_task(self._render_queue, script_path, 
                task_id, output_file=out_file, submit=True, 
                log_path=script_path + '.log')

        tasks_info_config.write(tasks_info_file)
        os.chmod(tasks_info_file, 0660)

        cur_op += 1
        progress_dialog.setValue(cur_op)

        if not self._debug_mode:

            progress_dialog.setLabelText("Sending submission report...")

            # send msg...
            msg_title = "Queue submission report: " + \
                now.strftime("%Y/%m/%d %H:%M:%S")
            msg_body = "Submitted the following task for " + \
                ptask.spec + ":\n\n"
            msg_body += "  Product representation: " + product_repr.spec + "\n"
            msg_body += "  Description: " + self._version_note + "\n"
            msg_body += "  Render queue: " + self._render_queue + "\n"
            msg_body += "  Frames: " + str(self._frange) + "\n"
            msg_body += "      Task ID: " + task_id + "\n"
            msg_body += "      Scripts directory: " + queue_dir + "\n"
            msg_body += "\n"

            dk_config = ptask.area.config(DK_CONFIG_PATH, 
                composite_ancestors=True, composite_method="append")
            recipients = dk_config.get('notify', [])
            recipients.append(current_username())
            recipients = emails_from_unames(recipients)
            notification = Notification(msg_title, msg_body, recipients,
                sender=User.current().email)
            notification.send_email()

        cur_op += 1
        progress_dialog.setValue(cur_op)
        progress_dialog.close()
コード例 #33
0
ファイル: sync.py プロジェクト: DarkRoseAM/dpa-pipe
    def validate(self):

        # ---- make sure the supplied specs match actual ptasks,
        #      set the properties

        try:
            self._source = PTask.get(self.source)
        except PTaskError:
            raise ActionError(
                "Unable to retrieve ptask from source argument: " + \
                    str(self.source)
            )

        try:
            self._destination = PTask.get(self.destination)
        except PTaskError:
            raise ActinError(
                "Unable to retrieve ptask from destination argument: " + \
                    str(self.destination),
                self,
            )

        self._source_latest_version = self.source.latest_version
        self._destination_latest_version = self.destination.latest_version

        # ---- make sure the ptasks are of the same type

        #if self.source.type != self.destination.type:
        #    raise ActionError(
        #        "Source and destination ptasks must be of the same type. " + \
        #            self.source.type + " != " + self.destination.type
        #    )

        # ---- if the target_type is not ptask, then the calling code has
        #      overridden the target type. make sure the source and destination
        #      types match the target type.

        target_type = self.__class__.target_type
        if target_type != "ptask":
            if self.source.type.lower() != target_type:
                raise ActionError("Source type must be a " + target_type)
            elif self.destination.type.lower() != target_type:
                raise ActionError("Destination type must a " + target_type)

        # ---- determine the source and destination versions and their locations

        if self.source_version:
            try:
                self._source_version = _get_ptask_version(
                    self.source,
                    self.source_version,
                )
            except TypeError as e:
                raise ActionError(str(e))

            source_location_code = self.source_version.location_code
        else:
            source_location_code = self.source_latest_version.location_code

        if self.destination_version:
            try:
                self._destination_version = _get_ptask_version(
                    self.destination, 
                    self.destination_version,
                )
            except TypeError as e:
                raise ActionError(str(e))

            destination_location_code = self.destination_version.location_code
        else:
            destination_location_code = \
                self.destination_latest_version.location_code

        # one of source or dest must be the current loation, unless the source
        # and destination are the same ptask. In that case, we'll assume the
        # goal is to sync the ptask to the current location or to source 
        # directories/versions within the ptask

        cur_loc_code = current_location_code()

        if self.source == self.destination:
            location_override = Location.current()
        else:
            if (source_location_code != cur_loc_code and 
                destination_location_code != cur_loc_code):
                raise ActionError(
                    "One of source or destination must be this location.",
                )
            location_override = None

        # ---- determine the source and desination paths

        self._source_path = self._get_path(
            ptask=self.source, 
            version=self.source_version, 
            latest_version=self.source_latest_version,
            directory=self.source_directory,
        )

        self._destination_path = self._get_path(
            ptask=self.destination, 
            version=self.destination_version, 
            latest_version=self.destination_latest_version,
            directory=self.destination_directory,
            location_override=location_override,
        )

        # ---- get the includes/excludes based on filter rules

        (includes, excludes) = self._get_filter_rules(self.destination)

        # exclude child ptask directories from the source
        for child in self.source.children:
            child_dir = os.path.sep + child.name
            excludes.append(child_dir)

        self._includes = includes
        self._excludes = excludes
コード例 #34
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def prompt(self):

        parent_spec = PTaskSpec.parent(self.spec)
        template_options = []

        if parent_spec:
            par_ptask = PTask.get(parent_spec)
            par_ptask_type = par_ptask.ptask_type
        else:
            par_ptask_type = 'none'

        ptask_area = PTaskArea(parent_spec, validate=False)
        master_config = ptask_area.config(
            PROJECT_MASTER_CONFIG_PATH,
            composite_ancestors=True,
        )

        if not master_config or not hasattr(master_config, 'hierarchy'):
            raise ActionError("Unable to find project master config.")

        if not self.ptask_type in master_config.hierarchy[par_ptask_type]:
            raise ActionError(
                "Cannot create '{t}' ptask inside '{p}' ptask".format(
                    t=self.ptask_type,
                    p=par_ptask_type,
                ))

        # ---- prompt for missing fields
        if not self.source and self.ptask_type in master_config.templates:
            for template_spec in master_config.templates[self.ptask_type]:
                trimmed_spec = re.sub("^templates?=",
                                      "",
                                      template_spec,
                                      flags=re.IGNORECASE)
                template_options.append(
                    (re.sub("[=_-]+", " ",
                            trimmed_spec).title(), template_spec))

            self._source = Output.prompt_menu(
                "Select a template to source",
                prompt_str="Selection",
                options=template_options,
                help_str="Please choose from the templates listed.",
                none_option=True,
                custom_prompt="Custom Source",
                custom_blank=False)

        # see if the ptask already exists
        if not self.ptask:
            try:
                self._ptask = PTask.get(self.spec)
            except PTaskError:
                pass
            else:
                if not self.force:
                    raise ActionAborted("PTask already exists.")
                else:
                    if not self._description:
                        self._description = self.ptask.description
                    if not self._start_date:
                        self._start_date = self.ptask.start_date
                    if not self._due_date:
                        self._due_date = self.ptask.due_date

        if (not self.description or not self.start_date or not self.due_date):

            if self.force:
                raise ActionError(
                    "Cannot force creation without required fields.")
            else:
                print "\nPlease enter information about this new {b}{t}{r}:".\
                    format(
                        b=Style.bright,
                        t=self.ptask_type,
                        r=Style.reset,
                    )

        ptask_display = " [{pt}] {b}{s}{r}".format(
            pt=self.ptask_type,
            b=Style.bright,
            s=self.spec,
            r=Style.reset,
        )

        if not self.description:
            self._description = Output.prompt(
                '{pd} description'.format(pd=ptask_display),
                blank=False,
            )

        if not self.start_date:
            self._start_date = Output.prompt_date(
                '{pd} start date'.format(pd=ptask_display),
                blank=False,
            )

        if not self.due_date:
            self._due_date = Output.prompt_date(
                '{pd} due date'.format(pd=ptask_display),
                blank=False,
            )
コード例 #35
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        # need to identify the product version being subscribed to and the
        # ptask version subscribing to it.

        # get the product
        if not isinstance(self._product, Product):
            try:
                self._product = Product.get(self._product)
            except ProductError:
                raise ActionError("Unable to find product: " + str(self._product))

        # get ptask
        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Unable to find ptask: " + str(self._ptask))

        # find the version to subscribe to
        if isinstance(self._product_version, ProductVersion):
            pass
        elif self._product_version:
            matches = ProductVersion.list(product=self.product.spec, number=int(self._product_version))
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find product '{p}' at version '{v}'".format(p=self.product.spec, v=self._product_version)
                )
            else:
                self._product_version = matches[0]
        else:
            # get the official version
            official_version = self._product.official_version
            if official_version:
                self._product_version = official_version
            else:
                # get the latest, non-deprecated version
                latest_published = self._product.latest_published()
                if latest_published:
                    self._product_version = latest_published
                else:
                    raise ActionError("No available versions of product '{p}'".format(p=self._product.spec))

        # find the version of the ptask doing the subscribing
        if isinstance(self._ptask_version, PTaskVersion):
            pass
        elif self._ptask_version:
            matches = PTaskVersion.list(ptask=self._ptask.spec, number=self._ptask_version)
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find ptask '{p}' at version '{v}'".format(p=self._ptask.spec, v=self._ptask_version)
                )
            else:
                self._ptask_version = matches[0]
        else:
            self._ptask_version = self._ptask.latest_version

        # XXX the rules below need to be exposed outside of just the create
        # code. UIs, for example, should be able to check these cases before
        # allowing the user to perform actions...

        # if this ptask has any existing published versions, error out
        published = ProductVersion.list(ptask_version=self._ptask_version, published=True)
        if len(published) > 0:
            raise ActionError(
                "Unable to create new subscription. This ptask version "
                + "already has published product versions.\n"
                + "You need to version up to modify subscriptions."
            )

        # see if there is an existing subscription:
        self._existing_sub = self._ptask_version.is_subscribed(self._product)
        if self._existing_sub:

            if self._existing_sub.product_version_spec == self._product_version.spec:
                raise ActionError("Subscription already exists!")

        if self._product_version.deprecated:
            raise ActionError("Product version is deprecated. Specify an alternate version.")

        # make sure product is published or from same ptask
        if not self._product_version.published and not self._product.ptask_spec == self._ptask.spec:
            raise ActionError("Product version is not published. Specify a published version.")
コード例 #36
0
ファイル: env.py プロジェクト: liudger/dpa-pipe
    def _print_ptask_env(self):

        # remove any whitespace on the head/tail of the spec
        spec = self.spec.strip()
        ptask_area = None

        if self.version:
            spec = PTaskSpec.VERSION.join([spec, str(self.version)])

        replace_match = re.match("\.?/([=\w]+)/([=\w]+)/", spec)

        # handle 'none' as a valid spec - unset current ptask (set it to root)
        if spec.lower() == 'none':
            spec = ""
            full_spec = PTaskSpec.get(spec)
            try:
                ptask_area = PTaskArea(full_spec)
            except:
                pass

        # special character '-' indicates use the last set ptask spec
        elif spec == "-":
            ptask_area = PTaskArea.previous()

        # set to a similar ptask with text replacement
        elif replace_match:

            cur_area_spec = PTaskArea.current().spec
            repl_spec = cur_area_spec.replace(replace_match.group(1),
                                              replace_match.group(2))
            try:
                ptask_area = PTaskArea(repl_spec)
            except:
                pass

        # use the supplied spec relative to the current ptask
        else:

            relative_to = PTaskArea.current().spec

            while ptask_area is None:

                try:
                    full_spec = PTaskSpec.get(spec, relative_to=relative_to)
                except PTaskSpecError as e:
                    raise ActionError(str(e))

                try:
                    # if this is successful, we'll break out of the while
                    ptask_area = PTaskArea(full_spec)
                except PTaskAreaError as e:
                    # no match, check the parent relative spec
                    relative_to = PTaskSpec.parent(relative_to)
                    # there is no parent, break out of the while
                    if relative_to is None:
                        break

        # dump out commands used for setting the environment for the supplied
        # spec.

        if not ptask_area:
            raise ActionError(
                "Could not determine ptask area from: " + str(spec), )

        ptask = None

        # delay the db query to this point to prevent multiple, unnecessary db
        # queries. if we're at this point, we know there's at least a
        # corresponding directory on disk.
        if ptask_area.base_spec:
            try:
                ptask = PTask.get(ptask_area.base_spec)
            except PTaskError as e:
                pass

        if not ptask and ptask_area.spec != "":
            raise ActionError("Could not determine ptask from: " + str(spec))

        ptask_area.set(shell=self.shell, ptask=ptask)
コード例 #37
0
ファイル: env.py プロジェクト: chippey/dpa-pipe
    def _print_ptask_env(self):

        # remove any whitespace on the head/tail of the spec
        spec = self.spec.strip()
        ptask_area = None

        if self.version:
            spec = PTaskSpec.VERSION.join([spec, str(self.version)])
            

        replace_match = re.match("\.?/([=\w]+)/([=\w]+)/", spec)

        # handle 'none' as a valid spec - unset current ptask (set it to root)
        if spec.lower() == 'none':
            spec = ""
            full_spec = PTaskSpec.get(spec)
            try:
                ptask_area = PTaskArea(full_spec)
            except:
                pass

        # special character '-' indicates use the last set ptask spec
        elif spec == "-":
            ptask_area = PTaskArea.previous()

        # set to a similar ptask with text replacement
        elif replace_match:

            cur_area_spec = PTaskArea.current().spec
            repl_spec = cur_area_spec.replace(
                replace_match.group(1), replace_match.group(2))
            try:
                ptask_area = PTaskArea(repl_spec)
            except:
                pass
            
        # use the supplied spec relative to the current ptask
        else:

            relative_to = PTaskArea.current().spec

            while ptask_area is None:

                try:
                    full_spec = PTaskSpec.get(spec, relative_to=relative_to)
                except PTaskSpecError as e:
                    raise ActionError(str(e))

                try:
                    # if this is successful, we'll break out of the while
                    ptask_area = PTaskArea(full_spec)
                except PTaskAreaError as e: 
                    # no match, check the parent relative spec
                    relative_to = PTaskSpec.parent(relative_to)
                    # there is no parent, break out of the while
                    if relative_to is None:
                        break

        # dump out commands used for setting the environment for the supplied
        # spec.

        if not ptask_area:
            raise ActionError(
                "Could not determine ptask area from: " + str(spec), 
            )

        ptask = None

        # delay the db query to this point to prevent multiple, unnecessary db
        # queries. if we're at this point, we know there's at least a
        # corresponding directory on disk. 
        if ptask_area.base_spec:
            try:
                ptask = PTask.get(ptask_area.base_spec)
            except PTaskError as e:
                pass

        if not ptask and ptask_area.spec != "":
            raise ActionError("Could not determine ptask from: " + str(spec))
        
        ptask_area.set(shell=self.shell, ptask=ptask)
コード例 #38
0
ファイル: __init__.py プロジェクト: chippey/dpa-pipe
 def ptask(self):
     return PTask.get(self.ptask_spec)
コード例 #39
0
ファイル: utils.py プロジェクト: liudger/dpa-pipe
def create_product_before_render(node=None):

    if not node:
        node = nuke.thisNode()

    if not node.knob('product_name') or not node.knob('product_desc'):
        raise Exception("The supplied node is not a WriteProduct node.")

    print "Creating product for write node... " + str(node)

    ptask_area = PTaskArea.current()
    ptask = PTask.get(ptask_area.spec)

    if ptask_area.version:
        ptask_version = ptask.version(ptask_area.version)
    else:
        ptask_version = ptask.latest_version

    category = 'imgseq'

    file_type = node['file_type'].value()
    if not file_type:
        file_type = 'exr'

    product_name = node['product_name'].value()
    product_desc = node['product_desc'].value()
    product_ver_note = node['product_ver_note'].value()

    if not product_desc:
        raise Exception("Please enter a product description.")

    width = nuke.value(node.name() + '.width')
    height = nuke.value(node.name() + '.height')
    resolution = width + 'x' + height

    create_action_cls = ActionRegistry().get_action('create', 'product')
    if not create_action_cls:
        raise Exception("Unable to find product creation action.")

    create_action = create_action_cls(
        product=product_name,
        ptask=ptask.spec,
        version=ptask_version.number,
        category=category,
        description=product_desc,
        file_type=file_type,
        resolution=resolution,
        note=product_ver_note,
    )

    try:
        create_action()
    except ActionError as e:
        raise Exception("Unable to create product: " + str(e))

    out_path = os.path.join(create_action.product_repr.area.path,
                            product_name + '.####.' + file_type)

    node['file'].setValue(out_path)

    return create_action.product_repr
コード例 #40
0
ファイル: maya.py プロジェクト: liudger/dpa-pipe
    def _output_options(self):

        output_type_lbl = QtGui.QLabel("Output:")
        output_type = QtGui.QComboBox()
        output_type.addItems(['Automatic', 'Manual'])

        header_layout = QtGui.QHBoxLayout()
        header_layout.addStretch()
        header_layout.addWidget(output_type_lbl)
        header_layout.addWidget(output_type)
        header_layout.addStretch()

        # ---- auto

        cur_area = PTaskArea.current()
        self._cur_ptask = PTask.get(cur_area.spec)
        if self._cur_ptask:
            self._version = \
                cur_area.version or self._cur_ptask.latest_version.number
        else:
            self._cur_ptask = None
            self._version = "None"

        ptask_lbl = QtGui.QLabel("PTask:")
        ptask_edit = QtGui.QLineEdit(str(self._cur_ptask))
        ptask_edit.setReadOnly(True)

        version_num = QtGui.QLabel("<B>v" + str(self._version) + "</B>")

        auto_layout = QtGui.QGridLayout()
        auto_layout.addWidget(ptask_lbl, 0, 0, QtCore.Qt.AlignRight)
        auto_layout.addWidget(ptask_edit, 0, 1)
        auto_layout.addWidget(version_num, 0, 2, QtCore.Qt.AlignLeft)
        auto_layout.setColumnStretch(0, 0)
        auto_layout.setColumnStretch(1, 1000)

        auto_widgets = QtGui.QWidget()
        auto_widgets.setLayout(auto_layout)

        # ---- manual

        dir_lbl = QtGui.QLabel("Directory:")
        self._dir_edit = QtGui.QLineEdit(os.getcwd())

        dir_btn = QtGui.QPushButton()
        dir_btn.setFlat(True)
        dir_btn_size = QtCore.QSize(22, 22)
        dir_btn.setFixedSize(dir_btn_size)
        dir_btn.setIcon(QtGui.QIcon(self.__class__._dir_path))
        dir_btn.setIconSize(dir_btn_size)

        dir_dialog = QtGui.QFileDialog(self, 'Output directory', 
            os.getcwd())
        dir_dialog.setFileMode(QtGui.QFileDialog.Directory)
        dir_dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True)
        dir_dialog.setOption(QtGui.QFileDialog.DontResolveSymlinks, True)
        dir_dialog.setOption(QtGui.QFileDialog.HideNameFilterDetails, True)
        dir_dialog.fileSelected.connect(self._dir_edit.setText)

        dir_btn.clicked.connect(dir_dialog.show)

        manual_layout = QtGui.QGridLayout()
        manual_layout.setContentsMargins(0, 0, 0, 0)
        manual_layout.addWidget(dir_lbl, 0, 0, QtCore.Qt.AlignRight)
        manual_layout.addWidget(self._dir_edit, 0, 1)
        manual_layout.addWidget(dir_btn, 0, 2)
        manual_layout.setColumnStretch(0, 0)
        manual_layout.setColumnStretch(1, 1000)
        manual_layout.setColumnStretch(2, 0)

        manual_widgets = QtGui.QWidget()
        manual_widgets.setLayout(manual_layout)

        self._output_stack = QtGui.QStackedWidget()
        self._output_stack.addWidget(auto_widgets)
        self._output_stack.addWidget(manual_widgets)

        output_type.activated.connect(self._output_stack.setCurrentIndex)

        # ---- layout

        output_layout = QtGui.QVBoxLayout()
        output_layout.addLayout(header_layout)
        output_layout.addWidget(self._output_stack)

        return output_layout 
コード例 #41
0
ファイル: houdini.py プロジェクト: chippey/dpa-pipe
    def _render_to_product(self):

        # get render node reference
        render_node = self.session.hou.node(self._node_to_render)

        # ---- progress dialog
        num_ops = 8
        cur_op = 0
        progress_dialog = QtGui.QProgressDialog(
            "Product render...", "", cur_op, num_ops, self)
        progress_dialog.setWindowTitle("Dark Knight is busy...")
        progress_dialog.setAutoReset(False)
        progress_dialog.setLabelText("Preparing nuke file for rendering...")
        progress_dialog.show()

        #########################################
        # ensure the product has been created
        #########################################
        progress_dialog.setLabelText("Creating product...")

        if not render_node.type().name()=='ifd' or not self._version_note:
            raise Exception("The supplied node is not a WriteProduct node.")

        print "Creating product for node... " + str(render_node)

        ptask_area = PTaskArea.current()
        ptask = PTask.get(ptask_area.spec)

        if ptask_area.version:
            ptask_version = ptask.version(ptask_area.version)
        else:
            ptask_version = ptask.latest_version

        category = 'imgseq'
        file_type = 'exr'

        product_name = render_node.name()
        product_desc = render_node.name() + " mantra render"
        product_ver_note = self._version_note

        camera_node = self.session.hou.node(render_node.evalParm('camera'))
        if not camera_node:
            raise Exception("Camera specified is not valid.")
        width = camera_node.evalParm("resx")
        height = camera_node.evalParm("resy")
        resolution = "%sx%s" % (width, height)
            
        create_action_cls = ActionRegistry().get_action('create', 'product')
        if not create_action_cls:
            raise Exception("Unable to find product creation action.")

        create_action = create_action_cls(
            product=product_name,
            ptask=ptask.spec,
            version=ptask_version.number,
            category=category,
            description=product_desc,
            file_type=file_type,
            resolution=resolution,
            note=product_ver_note,
        )

        try:
            create_action()
        except ActionError as e:
            raise Exception("Unable to create product: " + str(e))

        # provision the ifd directory
        try:
            create_action.product_repr.area.provision('ifd')
        except Exception as e:
            raise Exception(
                "Unable to create ifd file directory: " + str(e))

        ifd_dir = os.path.join(create_action.product_repr.area.path,
            'ifd', product_name + '.$F4.ifd')
        out_path = os.path.join(create_action.product_repr.area.path,
            product_name + '.$F4.' + file_type)

        # by default, the mantra frame range has an expression on frame numbers
        render_node.parm('f1').deleteAllKeyframes()
        render_node.parm('f2').deleteAllKeyframes()

        # set frange
        render_node.parm('trange').set(1)
        render_node.parm('f1').set(self._frange.start)
        render_node.parm('f2').set(self._frange.end)
        render_node.parm('f3').set(self._frange.step)

        # set output
        render_node.parm('soho_outputmode').set(1)
        render_node.parm('soho_diskfile').set(ifd_dir)
        render_node.parm('soho_diskfile').disable(0)
        render_node.parm('vm_picture').set(out_path)
        render_node.parm('soho_mkpath').set(1)

        product_repr = create_action.product_repr
        product_repr_area = product_repr.area

        cur_op += 1
        progress_dialog.setValue(cur_op)

        #########################################
        # create ifd files
        #########################################
        progress_dialog.setLabelText("Generating ifd files...")
        render_node.parm('execute').pressButton()
        ifd_file_list = glob.glob(
                            os.path.join(
                                create_action.product_repr.area.path,
                                'ifd', '*.ifd')
                            )
        for ifd_file in ifd_file_list:
            os.chmod(ifd_file, 0770)

        cur_op += 1
        progress_dialog.setValue(cur_op)

        #########################################
        # sync current work area to version snapshot to render from
        #########################################
        progress_dialog.setLabelText("Sync'ing the latest work...")

        try:
            self.session.save() 
            self._sync_latest()
        except Exception as e:
            self._show_error("Unable to save & sync the latest work: " + str(e))
            self.setEnabled(True)
            progress_dialog.close()
            return

        cur_op += 1
        progress_dialog.setValue(cur_op)

        #########################################
        # ensure queue directory exists
        #########################################
        progress_dialog.setLabelText("Provisioning the queue directory...")

        try:
            product_repr_area.provision('queue')
        except Exception as e:
            raise DarkKnightError(
                "Unable to create queue scripts directory: " + str(e))

        cur_op += 1
        progress_dialog.setValue(cur_op)

        out_dir = product_repr_area.path
        ifd_dir = product_repr_area.dir(dir_name='ifd')
        queue_dir = product_repr_area.dir(dir_name='queue')
        tasks_info_file = os.path.join(queue_dir, 'tasks_info.cfg')
        tasks_info_config = Config()

        cur_op += 1
        progress_dialog.setValue(cur_op)


        #########################################
        # buidling queue scripts
        #########################################
        progress_dialog.setLabelText("Building the queue script...")

        # # dpaset command to run
        dpaset_cmd = 'eval "`dpa env ptask {pt}@{vn}`"'.format(
            pt=ptask.spec, vn=ptask_version.number)

        # write out queue shell scripts
        frame_scripts = []
        for frame in self._frame_list:

            frame_padded = str(frame).zfill(4)

            ifd_file = os.path.join(ifd_dir, 
                "{pn}.{fn}.ifd".format(pn=product_name, fn=frame_padded))

            script_path = os.path.join(queue_dir, 
                "{pn}.{fn}.sh".format(pn=product_name, fn=frame_padded))

            out_file = os.path.join(out_dir, 
                "{pn}.{fn}.{ft}".format(pn=product_name, fn=frame_padded, ft=file_type) )

            render_cmd = "/opt/hfs14/bin/mantra -f {ifd} -V 2a".\
                format(
                    ifd=ifd_file
                )

            with open(script_path, "w") as script_file:
                script_file.write("#!/bin/bash\n\n")

                # XXX these should happen automatically in the queue...
                script_file.write("source /DPA/wookie/dpa/bash/startup.bash\n")
                script_file.write("pipeup\n\n")

                script_file.write("# set the ptask version to render\n")
                script_file.write(dpaset_cmd + "\n\n")

                script_file.write("# render!\n")
                script_file.write(render_cmd + "\n\n")

            frame_scripts.append((frame_padded, script_path, out_file))

            os.chmod(script_path, 0770)

        cur_op += 1
        progress_dialog.setValue(cur_op)


        ################################################
        # submit to the queue
        ################################################
        now = datetime.datetime.now()
        task_id_base = get_unique_id(product_repr_area.spec, dt=now)

        frame_tasks = []
        # create frame tasks
        for (frame, frame_script, out_file) in frame_scripts:

            progress_dialog.setLabelText(
                "Submitting frame: " + frame_script)

            task_id = task_id_base + "_" + frame

            if not self._debug_mode:

                # create tasks, don't actually submit yet
                create_queue_task(self._render_queue, frame_script, task_id,
                    output_file=out_file, submit=False, 
                    log_path=frame_script + '.log')

                frame_tasks.append((frame, task_id))
                #
                #  resubmit frame-by-frame because 
                #  group submit seems to be occasionally
                #  having problems.
                os.system("cqresubmittask {qn} {tid}".format(
                    qn=self._render_queue, tid=task_id))

        cur_op += 1
        progress_dialog.setValue(cur_op)

        ################################################
        # task info stuff, allows task ids to 
        # be retrieved with product spec
        ################################################
        progress_dialog.setLabelText("Creating task info file...")

        tasks_info_file = os.path.join(queue_dir, 'tasks_info.cfg')
        tasks_info_config = Config()
        tasks_info_config.add('base_id', task_id_base)

        frame_info = Config()
        for (frame, task_id) in frame_tasks:
            frame_info.add(str(frame), task_id)
        tasks_info_config.add('frame_ids', frame_info)

        tasks_info_config.write(tasks_info_file)
        os.chmod(tasks_info_file, 0660)

        cur_op += 1
        progress_dialog.setValue(cur_op)


        ################################################
        # email report
        ################################################
        if not self._debug_mode:
            # send msg...
            msg_title = "Queue submission report: " + \
                now.strftime("%Y/%m/%d %H:%M:%S")
            msg_body = "Submitted the following tasks for " + \
                ptask.spec + ":\n\n"
            msg_body += "  Description: " + self._version_note + "\n"
            msg_body += "  Resolution: " + resolution + "\n"

            msg_body += "  Render queue: " + self._render_queue + "\n"
            msg_body += "  Frames: " + str(self._frange) + "\n"
            msg_body += "  Ifd directory: " + ifd_dir + "\n"
            msg_body += "\n" 

            msg_body += "      Base task ID: " + task_id_base + "\n"
            msg_body += "      Product representation: " + \
                product_repr.spec + "\n"
            msg_body += "      Scripts directory: " + queue_dir + "\n"
            msg_body += "\n" 

            dk_config = ptask.area.config(DK_CONFIG_PATH, 
                composite_ancestors=True, composite_method="append")
            recipients = dk_config.get('notify', [])
            recipients.append(current_username())
            recipients = emails_from_unames(recipients)
            notification = Notification(msg_title, msg_body, recipients,
                sender=User.current().email)
            notification.send_email()
            print recipients

        cur_op += 1
        progress_dialog.setValue(cur_op)
        progress_dialog.close()
コード例 #42
0
ファイル: sync.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        # ---- make sure the supplied specs match actual ptasks,
        #      set the properties

        try:
            self._source = PTask.get(self.source)
        except PTaskError:
            raise ActionError(
                "Unable to retrieve ptask from source argument: " + \
                    str(self.source)
            )

        try:
            self._destination = PTask.get(self.destination)
        except PTaskError:
            raise ActinError(
                "Unable to retrieve ptask from destination argument: " + \
                    str(self.destination),
                self,
            )

        self._source_latest_version = self.source.latest_version
        self._destination_latest_version = self.destination.latest_version

        # ---- make sure the ptasks are of the same type

        #if self.source.type != self.destination.type:
        #    raise ActionError(
        #        "Source and destination ptasks must be of the same type. " + \
        #            self.source.type + " != " + self.destination.type
        #    )

        # ---- if the target_type is not ptask, then the calling code has
        #      overridden the target type. make sure the source and destination
        #      types match the target type.

        target_type = self.__class__.target_type
        if target_type != "ptask":
            if self.source.type.lower() != target_type:
                raise ActionError("Source type must be a " + target_type)
            elif self.destination.type.lower() != target_type:
                raise ActionError("Destination type must a " + target_type)

        # ---- determine the source and destination versions and their locations

        if self.source_version:
            try:
                self._source_version = _get_ptask_version(
                    self.source,
                    self.source_version,
                )
            except TypeError as e:
                raise ActionError(str(e))

            source_location_code = self.source_version.location_code
        else:
            source_location_code = self.source_latest_version.location_code

        if self.destination_version:
            try:
                self._destination_version = _get_ptask_version(
                    self.destination, 
                    self.destination_version,
                )
            except TypeError as e:
                raise ActionError(str(e))

            destination_location_code = self.destination_version.location_code
        else:
            destination_location_code = \
                self.destination_latest_version.location_code

        # one of source or dest must be the current loation, unless the source
        # and destination are the same ptask. In that case, we'll assume the
        # goal is to sync the ptask to the current location or to source 
        # directories/versions within the ptask

        cur_loc_code = current_location_code()

        if self.source == self.destination:
            location_override = Location.current()
        else:
            if (source_location_code != cur_loc_code and 
                destination_location_code != cur_loc_code):
                raise ActionError(
                    "One of source or destination must be this location.",
                )
            location_override = None

        # ---- determine the source and desination paths

        self._source_path = self._get_path(
            ptask=self.source, 
            version=self.source_version, 
            latest_version=self.source_latest_version,
            directory=self.source_directory,
        )

        self._destination_path = self._get_path(
            ptask=self.destination, 
            version=self.destination_version, 
            latest_version=self.destination_latest_version,
            directory=self.destination_directory,
            location_override=location_override,
        )

        # ---- get the includes/excludes based on filter rules

        (includes, excludes) = self._get_filter_rules(self.destination)

        # exclude child ptask directories from the source
        for child in self.source.children:
            child_dir = os.path.sep + child.name
            excludes.append(child_dir)

        self._includes = includes
        self._excludes = excludes
コード例 #43
0
ファイル: nuke_.py プロジェクト: chippey/dpa-pipe
    def _render_to_product(self):

        # add the version note for the product
        render_node = self.session.nuke.toNode(self._node_to_render)
        render_node['product_ver_note'].setValue(self._version_note)

        # ---- progress dialog

        num_ops = 6
        cur_op = 0

        progress_dialog = QtGui.QProgressDialog(
            "Product render...", "", cur_op, num_ops, self)
        progress_dialog.setWindowTitle("Dark Knight is busy...")
        progress_dialog.setAutoReset(False)
        progress_dialog.setLabelText("Preparing nuke file for rendering...")
        progress_dialog.show()

        # ensure the product has been created
        progress_dialog.setLabelText("Creating product...")

        product_repr = create_product_before_render(node=render_node)
        product_repr_area = product_repr.area

        cur_op += 1
        progress_dialog.setValue(cur_op)

        # get timestamp for all the tasks being submitted
        now = datetime.datetime.now()

        ptask_area = PTaskArea.current()
        ptask = PTask.get(ptask_area.spec)

        if ptask_area.version:
            ptask_version = ptask.version(ptask_area.version)
        else:
            ptask_version = ptask.latest_version

        ptask_dir = ptask_area.dir()
        ver_dir = ptask_area.dir(version=ptask_version.number)

        nuke_file = self.session.nuke.root().name()
        nuke_file = nuke_file.replace(ptask_dir, ver_dir)

        file_base = os.path.splitext(os.path.split(nuke_file)[1])[0]

        # ---- sync current work area to version snapshot to render from

        progress_dialog.setLabelText("Sync'ing the latest work...")

        try:
            self.session.save() 
            self._sync_latest()
        except Exception as e:
            self._show_error("Unable to save & sync the latest work: " + str(e))
            self.setEnabled(True)
            progress_dialog.close()
            return

        cur_op += 1
        progress_dialog.setValue(cur_op)

        # make sure queue directory exists 

        progress_dialog.setLabelText("Provisioning the queue directory...")

        try:
            product_repr_area.provision('queue')
        except Exception as e:
            raise DarkKnightError(
                "Unable to create queue scripts directory: " + str(e))

        cur_op += 1
        progress_dialog.setValue(cur_op)

        queue_dir = product_repr_area.dir(dir_name='queue')
        tasks_info_file = os.path.join(queue_dir, 'tasks_info.cfg')
        tasks_info_config = Config()

        progress_dialog.setLabelText("Building the queue script...")

        # dpaset command to run
        dpaset_cmd = 'eval "`dpa env ptask {pt}@{vn}`"'.format(
            pt=ptask.spec, vn=ptask_version.number)

        frange_str = str(self._frange).replace("-", "_").replace(":", "_")

        script_path = os.path.join(queue_dir, 
            "{pn}.{fr}.sh".format(pn=render_node['product_name'].value(),
                fr=frange_str))

        render_cmd = "nuke --cont -f -F {fs}-{fe}x{step} -X {rn} -V 2 -x {nf}".\
            format(
                fs=self._frange.start,
                fe=self._frange.end,
                step=self._frange.step,
                rn=self._node_to_render,
                nf=nuke_file,
            )

        with open(script_path, "w") as script_file:
            script_file.write("#!/bin/bash\n\n")

            # XXX these should happen automatically in the queue...
            script_file.write("source /DPA/wookie/dpa/bash/startup.bash\n")
            script_file.write("pipeup\n\n")

            script_file.write("# set the ptask version to render\n")
            script_file.write(dpaset_cmd + "\n\n")

            script_file.write("# render!\n")
            script_file.write(render_cmd + "\n\n")

        os.chmod(script_path, 0770)

        cur_op += 1
        progress_dialog.setValue(cur_op)
            
        task_id = get_unique_id(product_repr_area.spec, dt=now)
        task_id += "_" + frange_str

        tasks_info_config.add('task_id', task_id)

        out_file = self.session.nuke.filename(render_node, 
            self.session.nuke.REPLACE)

        if not self._debug_mode:

            progress_dialog.setLabelText("Submitting to the queue...")

            create_queue_task(self._render_queue, script_path, 
                task_id, output_file=out_file, submit=True, 
                log_path=script_path + '.log')

        tasks_info_config.write(tasks_info_file)
        os.chmod(tasks_info_file, 0660)

        cur_op += 1
        progress_dialog.setValue(cur_op)

        if not self._debug_mode:

            progress_dialog.setLabelText("Sending submission report...")

            # send msg...
            msg_title = "Queue submission report: " + \
                now.strftime("%Y/%m/%d %H:%M:%S")
            msg_body = "Submitted the following task for " + \
                ptask.spec + ":\n\n"
            msg_body += "  Product representation: " + product_repr.spec + "\n"
            msg_body += "  Description: " + self._version_note + "\n"
            msg_body += "  Render queue: " + self._render_queue + "\n"
            msg_body += "  Frames: " + str(self._frange) + "\n"
            msg_body += "      Task ID: " + task_id + "\n"
            msg_body += "      Scripts directory: " + queue_dir + "\n"
            msg_body += "\n"

            dk_config = ptask.area.config(DK_CONFIG_PATH, 
                composite_ancestors=True, composite_method="append")
            recipients = dk_config.get('notify', [])
            recipients.append(current_username())
            recipients = emails_from_unames(recipients)
            notification = Notification(msg_title, msg_body, recipients,
                sender=User.current().email)
            notification.send_email()

        cur_op += 1
        progress_dialog.setValue(cur_op)
        progress_dialog.close()
コード例 #44
0
ファイル: update.py プロジェクト: DarkRoseAM/dpa-pipe
    def validate(self):

        # validate the ptask
        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Could not determine ptask from: {p}".format(
                    p=self._ptask))

        # find the version of the ptask to update
        if isinstance(self._ptask_version, PTaskVersion):
            if not self._ptask_version.ptask_spec == self._ptask_spec:
                raise ActionError(
                    "Supplied ptask version doesn't match supplied ptask.")
        elif self._ptask_version:
            matches = PTaskVersion.list(
                ptask=self._ptask.spec, number=self._ptask_version
            )
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find ptask '{p}' at version '{v}'".format(
                        p=self._ptask.spec, v=self._ptask_version
                    )
                )
            else:
                self._ptask_version = matches[0]
        else:
            self._ptask_version = self._ptask.latest_version

        # XXX rule
        
        # don't allow if ptask_version already has published products
        if self._ptask_version.published:
            raise ActionError(
                "Subscriptions can not be modified." + \
                "Version {v} of {p} has published products.".format(
                    v=self._ptask_version.number_padded, 
                    p=self._ptask.spec
                ))

        # XXX

        subs = [] 

        # valdiate the subscriptions to update
        if self._subs:

            # get explicit subs
            for sub in self._subs:

                if isinstance(sub, ProductSubscription):
                    subs_to_udpate.append(sub)
                    continue

                try:
                    sub = int(sub)
                except:
                    raise ActionError("Could not determine sub from: {s}".\
                        format(s=sub))
                else:
                    matches = ProductSubscription.list(id=sub)         
                    if len(matches) != 1:
                        raise ActionError("Unable to identify sub for id: " + \
                            str(sub))
                    else:
                        subs.append(matches[0])

        else:
            # all subs for ptask version
            subs.extend(self._ptask_version.subscriptions)

        self._subs = subs

        update_map = defaultdict(dict)

        for sub in subs:
            
            sub_product_ver = sub.product_version
            
            update_map[sub.id]['old'] = sub_product_ver

            if sub.locked:
                update_map[sub.id]['new'] = None
                update_map[sub.id]['note'] = 'Subscription locked'
                continue 

            if sub_product_ver.is_official:
                update_map[sub.id]['new'] = None
                update_map[sub.id]['note'] = 'Already subscribed to official'
                continue 

            sub_product = sub_product_ver.product

            official_ver = sub_product.official_version

            if official_ver and official_ver.number > sub_product_ver.number:
                update_map[sub.id]['new'] = official_ver
                update_map[sub.id]['note'] = 'Official version'
                continue 

            if sub.product_version.product.ptask.spec == self.ptask.spec:
                all_vers = [v for v in sub_product.versions]
            else:
                all_vers = [v for v in sub_product.versions if v.published]

            all_vers.sort(key=lambda v: v.number_padded)

            if all_vers:
                latest = all_vers[-1]
                if latest.number > sub_product_ver.number:
                    update_map[sub.id]['new'] = latest 
                    if latest.published:
                        update_map[sub.id]['note'] = 'Latest published version'
                    else:
                        update_map[sub.id]['note'] = 'Latest version'
                    continue 
                else:
                    update_map[sub.id]['new'] = None
                    if sub_product_ver.published:
                        update_map[sub.id]['note'] = \
                            'Already using latest published'
                    else:
                        update_map[sub.id]['note'] = 'Already using latest'
                    continue 
                    
            else:
                update_map[sub.id]['new'] = None
                update_map[sub.id]['note'] = 'No new versions'
                continue 

        self._update_map = update_map
コード例 #45
0
    def execute(self):

        ptasks = []

        # search the ptasks for specs matching the supplied string
        if PTaskSpec.WILDCARD in self.wild_spec:

            search_str = ",".join(
                filter(None,
                       self.wild_spec.strip().split(PTaskSpec.WILDCARD)))

            if not search_str:
                raise ActionError(
                    "Search is too broad. " + \
                    "Please supply a string to search against."
                )

            try:
                # XXX this is inefficient. need better filtering on the backend
                ptasks = PTask.list(search=search_str)
            except PTaskError:
                pass
        else:

            try:
                ptasks.append(PTask.get(self.wild_spec))
            except PTaskError:
                pass

        matching_ptasks = []

        # the rest api's search filter isn't that great. it doesn't maintain any
        # knowledge of order for the supplied filters. So, it will return ptasks
        # that match all of the search terms, but not necessarily in the order
        # supplied. Do one more match against the returned ptasks specs keeping
        # the order of the supplied wildcard spec.

        regex_spec = "^" + \
            self.wild_spec.replace(PTaskSpec.WILDCARD, "([\w=]+)?") + "$"
        regex_spec = re.compile(regex_spec)

        for ptask in ptasks:
            if regex_spec.match(ptask.spec):
                matching_ptasks.append(ptask)

        match_count = len(matching_ptasks)

        if match_count == 0:
            print '\nFound 0 ptasks matching: "{s}"\n'.format(s=self.wild_spec)
            return

        # define the fields names
        spec = "Spec"
        ptask_type = "Type"
        status = "Status"

        # define the look of the output
        output = Output()
        output.vertical_separator = None
        output.table_cell_separator = '  '
        output.table_header_separator = '-'

        if match_count == 1:
            output.title = "{s}: 1 match".format(s=self.wild_spec)
        else:
            output.title = "{s}: {n} matches".format(s=self.wild_spec,
                                                     n=match_count)

        # display order of the information
        output.header_names = [
            spec,
            ptask_type,
            status,
        ]

        for ptask in sorted(matching_ptasks, key=lambda p: p.spec):
            # add all the information
            output.add_item(
                {
                    spec: ptask.spec,
                    ptask_type: ptask.ptask_type,
                    status: ptask.status,
                },
                colors={
                    spec: Style.bright,
                })

        # dump the output as a list of key/value pairs
        output.dump(output_format='table')
コード例 #46
0
ファイル: create.py プロジェクト: liudger/dpa-pipe
    def validate(self):

        # need to identify the product version being subscribed to and the
        # ptask version subscribing to it.

        # get the product
        if not isinstance(self._product, Product):
            try:
                self._product = Product.get(self._product)
            except ProductError:
                raise ActionError("Unable to find product: " +
                                  str(self._product))

        # get ptask
        if not isinstance(self._ptask, PTask):
            try:
                cur_spec = PTaskArea.current().spec
                full_spec = PTaskSpec.get(self._ptask, relative_to=cur_spec)
                self._ptask = PTask.get(full_spec)
            except PTaskError:
                raise ActionError("Unable to find ptask: " + str(self._ptask))

        # find the version to subscribe to
        if isinstance(self._product_version, ProductVersion):
            pass
        elif self._product_version:
            matches = ProductVersion.list(product=self.product.spec,
                                          number=int(self._product_version))
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find product '{p}' at version '{v}'".format(
                        p=self.product.spec, v=self._product_version))
            else:
                self._product_version = matches[0]
        else:
            # get the official version
            official_version = self._product.official_version
            if official_version:
                self._product_version = official_version
            else:
                # get the latest, non-deprecated version
                latest_published = self._product.latest_published()
                if latest_published:
                    self._product_version = latest_published
                else:
                    raise ActionError(
                        "No available versions of product '{p}'".format(
                            p=self._product.spec))

        # find the version of the ptask doing the subscribing
        if isinstance(self._ptask_version, PTaskVersion):
            pass
        elif self._ptask_version:
            matches = PTaskVersion.list(ptask=self._ptask.spec,
                                        number=self._ptask_version)
            if len(matches) != 1:
                raise ActionError(
                    "Unable to find ptask '{p}' at version '{v}'".format(
                        p=self._ptask.spec, v=self._ptask_version))
            else:
                self._ptask_version = matches[0]
        else:
            self._ptask_version = self._ptask.latest_version

        # XXX the rules below need to be exposed outside of just the create
        # code. UIs, for example, should be able to check these cases before
        # allowing the user to perform actions...

        # if this ptask has any existing published versions, error out
        published = ProductVersion.list(ptask_version=self._ptask_version,
                                        published=True)
        if len(published) > 0:
            raise ActionError(
                "Unable to create new subscription. This ptask version " + \
                "already has published product versions.\n" + \
                "You need to version up to modify subscriptions."
            )

        # see if there is an existing subscription:
        self._existing_sub = self._ptask_version.is_subscribed(self._product)
        if self._existing_sub:

            if (self._existing_sub.product_version_spec == \
                self._product_version.spec):
                raise ActionError("Subscription already exists!")

        if self._product_version.deprecated:
            raise ActionError(
                "Product version is deprecated. Specify an alternate version.")

        # make sure product is published or from same ptask
        if (not self._product_version.published
                and not self._product.ptask_spec == self._ptask.spec):
            raise ActionError(
                "Product version is not published. Specify a published version."
            )
コード例 #47
0
ファイル: utils.py プロジェクト: chippey/dpa-pipe
def create_product_before_render(node=None):

    if not node:
        node = nuke.thisNode()

    if not node.knob('product_name') or not node.knob('product_desc'):
        raise Exception("The supplied node is not a WriteProduct node.")

    print "Creating product for write node... " + str(node)

    ptask_area = PTaskArea.current()
    ptask = PTask.get(ptask_area.spec)

    if ptask_area.version:
        ptask_version = ptask.version(ptask_area.version)
    else:
        ptask_version = ptask.latest_version

    category = 'imgseq'

    file_type = node['file_type'].value()
    if not file_type:
        file_type = 'exr'

    product_name = node['product_name'].value()
    product_desc = node['product_desc'].value()
    product_ver_note = node['product_ver_note'].value()

    if not product_desc:
        raise Exception("Please enter a product description.")

    width = nuke.value(node.name() + '.width')
    height = nuke.value(node.name() + '.height')
    resolution = width + 'x' + height
        
    create_action_cls = ActionRegistry().get_action('create', 'product')
    if not create_action_cls:
        raise Exception("Unable to find product creation action.")

    create_action = create_action_cls(
        product=product_name,
        ptask=ptask.spec,
        version=ptask_version.number,
        category=category,
        description=product_desc,
        file_type=file_type,
        resolution=resolution,
        note=product_ver_note,
    )

    try:
        create_action()
    except ActionError as e:
        raise Exception("Unable to create product: " + str(e))

    out_path = os.path.join(create_action.product_repr.area.path,
        product_name + '.####.' + file_type)

    node['file'].setValue(out_path)

    return create_action.product_repr
コード例 #48
0
ファイル: list.py プロジェクト: chippey/dpa-pipe
    def execute(self):

        ptasks = []

        # search the ptasks for specs matching the supplied string
        if PTaskSpec.WILDCARD in self.wild_spec:

            search_str = ",".join(
                filter(None,
                    self.wild_spec.strip().split(PTaskSpec.WILDCARD)
                )
            )

            if not search_str:
                raise ActionError(
                    "Search is too broad. " + \
                    "Please supply a string to search against."
                )

            try:
                # XXX this is inefficient. need better filtering on the backend
                ptasks = PTask.list(search=search_str)
            except PTaskError:
                pass
        else:
            
            try:
                ptasks.append(PTask.get(self.wild_spec))
            except PTaskError:
                pass

        matching_ptasks = []

        # the rest api's search filter isn't that great. it doesn't maintain any
        # knowledge of order for the supplied filters. So, it will return ptasks
        # that match all of the search terms, but not necessarily in the order
        # supplied. Do one more match against the returned ptasks specs keeping
        # the order of the supplied wildcard spec. 

        regex_spec = "^" + \
            self.wild_spec.replace(PTaskSpec.WILDCARD, "([\w=]+)?") + "$"
        regex_spec = re.compile(regex_spec)

        for ptask in ptasks:
            if regex_spec.match(ptask.spec):
                matching_ptasks.append(ptask)

        match_count = len(matching_ptasks)

        if match_count == 0:
            print '\nFound 0 ptasks matching: "{s}"\n'.format(s=self.wild_spec)
            return

        # define the fields names
        spec = "Spec"
        ptask_type = "Type"
        status = "Status"

        # define the look of the output
        output = Output()
        output.vertical_separator = None
        output.table_cell_separator = '  '
        output.table_header_separator = '-'

        if match_count == 1:
            output.title = "{s}: 1 match".format(s=self.wild_spec)
        else:
            output.title = "{s}: {n} matches".format(
                s=self.wild_spec, n=match_count)
        
        # display order of the information
        output.header_names = [
            spec, 
            ptask_type, 
            status,
        ]

        for ptask in sorted(matching_ptasks, key=lambda p: p.spec):
            # add all the information 
            output.add_item(
                {
                    spec: ptask.spec,
                    ptask_type: ptask.ptask_type,
                    status: ptask.status,
                },
                colors={
                    spec: Style.bright,
                }
            )

        # dump the output as a list of key/value pairs
        output.dump(output_format='table')
コード例 #49
0
 def ptask(self):
     return PTask.get(self.ptask_spec)