def clean_student_license(self, data, reply):
        file_path = data.get('file_path', None)

        try:
            helpers.clean_student_line(file_path)
            reply['success'] = True
        except Exception:
            if not reply['msg']:
                reply['msg'] = 'Something went wrong while cleaning student license: {}'.format(
                    traceback.format_exc())
            reply['success'] = False
Exemplo n.º 2
0
    def save_scene(self, notify=False):
        """
        Saves current scene and cleans invalid data
        :param notify: bool
        """

        tp.Dcc.clean_scene()
        tp.Dcc.save_current_scene(force=False)
        scene_name = tp.Dcc.scene_name()
        if not scene_name:
            LOGGER.warning('File was not saved!')
            return False

        if tp.is_maya():
            from tpDcc.dccs.maya.core import helpers
            helpers.clean_student_line()

        if notify:
            self.tray.show_message(title='Save File',
                                   msg='File saved successfully!')

        return True
Exemplo n.º 3
0
    def clean_student_license(self, file_path=''):
        if not dcc.is_maya():
            LOGGER.warning('Data must be accessed from within Maya!')
            return

        if file_path:
            file_to_clean = file_path
        else:
            file_to_clean = self.get_file()
        if not path.is_file(file_to_clean):
            LOGGER.warning('Impossible to reference invalid data file: {}'.format(file_path))
            return

        changed = helpers.clean_student_line(file_to_clean)
        if changed:
            LOGGER.debug('Cleaned student license from file: {}'.format(file_to_clean))
    def process(self, context, plugin):
        if not tp.is_maya():
            self.log.warning('Clean Student License Action is only available in Maya!')
            return False

        from tpDcc.dccs.maya.core import helpers

        scene_name = tp.Dcc.scene_name()
        if not scene_name:
            self.log.error('Error while cleaning student license. Save your scene first!')
            return False
        if not os.path.isfile(scene_name):
            self.log.error('Error while cleaning student license. File "{}" does not exist!'.format(scene_name))
            return False

        self.log.info('Cleaning student license ...')
        valid_clean = helpers.clean_student_line(scene_name)
        if not valid_clean:
            self.log.error('Was not possible to clean student license>!')
            return False

        self.log.info('Student License cleaned successfully!')

        return True
Exemplo n.º 5
0
    def _export_file(self, file_path, *args, **kwargs):

        # Retrieve master layout file path
        sequence_name = self._shot.get_sequence()
        if not sequence_name:
            LOGGER.warning(
                'Impossible to export shot file "{}" because is not linked to any sequence!'
                .format(self._shot.get_name()))
            return None
        sequence = artellapipe.SequencesMgr().find_sequence(sequence_name)
        if not sequence:
            LOGGER.warning(
                'Impossible to export shot file "{}" because sequence "{}" was not found in current project'
                .format(self._shot.get_name(), sequence_name))
            return None
        sequence_file_type = sequence.get_file_type('master')
        if not sequence_file_type:
            LOGGER.warning(
                'Impossible to export shot file "{}" because sequence file type "master" is not defined '
                'in current project'.format(self._shot.get_name()))
            return None

        master_file_path = sequence_file_type.get_file()
        if not master_file_path or not os.path.exists(master_file_path):
            LOGGER.warning(
                'Impossible to export shot file "{}" because master layout file "{}" does not exists!'
                .format(self._shot.get_name(), master_file_path))
            return None

        sequence_file_type.open_file()

        master_locked = False
        if os.path.isfile(master_file_path):
            valid_lock = artellapipe.FilesMgr().lock_file(master_file_path)
            master_locked = True
            if not valid_lock:
                LOGGER.warning('Was not possible to lock file: {}'.format(
                    master_file_path))
                return False

        sequence_file_type.open_file()

        file_path_name = os.path.basename(file_path)
        file_path_dir = os.path.dirname(file_path)
        if not os.path.isdir(file_path_dir):
            LOGGER.info('Creating export file path directory: {}'.format(
                file_path_dir))
            try:
                os.makedirs(file_path_dir)
            except Exception as exc:
                LOGGER.error(
                    'Error while creating export path directory: "{}" | {} | {}'
                    .format(file_path_dir, exc, traceback.format_exc()))
                return None

        try:
            if os.path.isfile(file_path):
                fileio.delete_file(file_path_name, file_path_dir)
            fileio.copy_file(master_file_path, file_path)
            LOGGER.info('Created new Shot File: {}'.format(file_path))
        except Exception as exc:
            LOGGER.error(
                'Error while copying shot file "{}" from master layout file "{}" | {} | {}'
                .format(file_path, master_file_path, exc,
                        traceback.format_exc()))
            return None

        if os.path.isfile(file_path):
            valid_lock = artellapipe.FilesMgr().lock_file(file_path)
            if not valid_lock:
                LOGGER.warning(
                    'Was not possible to lock file: {}'.format(file_path))

        tp.Dcc.open_file(file_path)

        shot_anim_file_type = self._shot.get_file_type('shot_layout_anim')
        if not shot_anim_file_type:
            LOGGER.warning(
                'Impossible to export shot "{}" because shot file type "shot_layout_anim" is not defined '
                'in current project'.format(self._shot.get_name()))
            return None

        start_frame = kwargs.get('start_frame', 101)
        valid_anim_export = shot_anim_file_type.export_file(
            start_frame=start_frame)
        if not valid_anim_export:
            LOGGER.warning('Layout Animation Export was not exported in file!')
            return None

        if master_locked:
            artellapipe.FilesMgr().unlock_file(master_file_path,
                                               warn_user=False)

        try:
            shot_anim_file_path = shot_anim_file_type.get_file()
            shot_anim_file_path_name = os.path.basename(shot_anim_file_path)
            shot_anim_file_path_directory = os.path.dirname(
                shot_anim_file_path)
            fileio.delete_file(shot_anim_file_path_name,
                               shot_anim_file_path_directory)
        except Exception as exc:
            LOGGER.warning(
                'Was not possible to remove Shot Layout Animation File: "{}" | {} | {}. Remove it manually'
                .format(shot_anim_file_path, exc, traceback.format_exc()))

        try:
            tp.Dcc.convert_fraction_keys_to_whole_keys(
                consider_selected_range=False)
        except Exception as exc:
            LOGGER.warning(
                'Could not resolve any keyframes on fractions of a frame: {} | {}'
                .format(exc, traceback.format_exc()))

        # Clean shot nodes that are not valid anymore
        all_shots = tp.Dcc.all_scene_shots()
        shots_to_delete = [
            shot for shot in all_shots if shot != self.get_name()
        ]
        tp.Dcc.delete_object(shots_to_delete)

        # Update timeline
        start_offset = self._shot.get_start_frame() - start_frame
        start_frame = self._shot.get_start_frame() - start_offset
        end_frame = self._shot.get_end_frame() - start_offset
        tp.Dcc.set_active_frame_range(start_frame, end_frame)

        # Update shot attributes
        self._shot.set_start_frame(start_frame)
        self._shot.set_end_frame(end_frame)

        # Remove cameras that does not belong to the shot
        camera_name = self._shot.get_camera()
        root_node = None
        all_cameras = tp.Dcc.get_all_cameras(full_path=True) or list()
        for camera in all_cameras:
            if not camera:
                continue
            base_name = tp.Dcc.node_short_name(camera)
            if base_name == camera_name:
                root_node = camera.split('|')[1]
                break
        if root_node:
            for camera in all_cameras:
                if not camera or not tp.Dcc.object_exists(camera):
                    continue
                base_name = tp.Dcc.node_short_name(camera)
                if base_name == camera_name:
                    continue
                reps = 0
                node_to_delete = camera
                camera_parent = tp.Dcc.node_parent(camera)
                while camera_parent != '|{}'.format(root_node) and reps < 10:
                    node_to_delete = camera_parent
                    camera_parent = tp.Dcc.node_parent(node_to_delete)
                    reps += 1
                tp.Dcc.delete_object(node_to_delete)
        else:
            for camera in all_cameras:
                if not camera:
                    continue
                base_name = tp.Dcc.node_short_name(camera)
                if base_name == camera_name:
                    continue
                tp.Dcc.delete_object(camera)

        # Force look through to shot camera
        tp.Dcc.look_through_camera(camera_name)

        # Save scene
        tp.Dcc.save_current_scene(force=True)
        if tp.is_maya():
            from tpDcc.dccs.maya.core import helpers
            helpers.clean_student_line()

        return True
def upload_new_asset_version(
        file_path=None,
        comment='Published new version with Artella Pipeline',
        skip_saving=False):
    """
    Adds a new file to the Artella server
    :param file_path:
    :param comment:
    :param skip_saving: When we publish textures we do not want to save the maya scene
    """

    if not file_path:
        file_path = tp.Dcc.scene_name()
    if not file_path:
        LOGGER.error(
            'File {} cannot be locked because it does not exists!'.format(
                file_path))
        return False

    msg = 'Making new version for {}'.format(file_path)
    LOGGER.info(msg)
    if artellapipe.project:
        artellapipe.project.message(msg)

    client = get_artella_client()

    valid_upload = False
    if file_path is not None and file_path != '':
        file_is_locked, is_locked_by_me, _, _ = client.check_lock(file_path)
        if file_is_locked and not is_locked_by_me:
            error_msg = 'File is locked by other user. Impossible to create new version'
            LOGGER.error(error_msg)
            if artellapipe.project:
                artellapipe.project.message(error_msg)
            return False

        if not skip_saving:
            if tp.Dcc.scene_is_modified():
                tp.Dcc.save_current_scene(force=True)

        if tp.is_maya():
            from tpDcc.dccs.maya.core import helpers
            if helpers.file_has_student_line(filename=file_path):
                helpers.clean_student_line(filename=file_path)
                if helpers.file_has_student_line(filename=file_path):
                    LOGGER.error(
                        'After updating model path the Student License could not be fixed again!'
                    )
                    return False

        msg = 'Saving new file version on Artella Server: {}'.format(file_path)
        LOGGER.info(msg)
        if artellapipe.project:
            artellapipe.project.message(msg)
        if comment is None:
            result = tp.Dcc.confirm_dialog(
                title='Artella Pipeline - Save New Version on Artella Server',
                message=msg,
                button=['Save', 'Cancel'],
                cancel_button='Cancel',
                dismiss_string='Cancel')
            if result == 'Save':
                comment = qtutils.get_comment(title='Comment')
            else:
                return False

        valid_upload = client.upload(file_path, comment=comment)
    else:
        msg = 'The file has not been created yet'
        LOGGER.debug(msg)
        tp.Dcc.warning(msg)
        tp.Dcc.confirm_dialog(
            title='Artella Pipeline - Failed to Make New Version',
            message=msg,
            button=['Ok'])

    if not valid_upload:
        msg = 'Failed to make new version of {}'.format(
            os.path.basename(file_path))
        tp.Dcc.confirm_dialog(
            title='Artella Pipeline - Failed to Make New Version',
            message=msg,
            button=['Ok'])
        return False

    return valid_upload