Exemple #1
0
    def update_paths(self, file_path=None, show_dialogs=True, call_post_function=True, skip_save=True):
        """
        Updates all file paths of the given file path to make sure that they point to valid Artella file paths

        :param str file_path:
        :param bool show_dialogs:
        :param bool call_post_function:
        :param bool skip_save:
        :return:
        """

        artella_drive_client = self.get_client(show_dialogs=False)
        if not artella_drive_client:
            return False

        if not file_path:
            file_path = dcc.scene_name()
        if not file_path:
            msg = 'No file paths given to convert. Impossible to update paths.'
            logger.warning(msg)
            if show_dialogs:
                dcc.show_warning(title='Artella - Failed to update paths', message=msg)
            return False

        file_paths = utils.force_list(file_path, remove_duplicates=True)

        converted_paths = list()
        for file_path in file_paths:

            local_path = artella_drive_client.translate_path(file_path)

            ext = os.path.splitext(local_path)[-1]
            if ext not in dcc.extensions() or not os.path.isfile(local_path):
                logger.info('Skipping non DCC scene file path from conversion: "{}"'.format(local_path))
                continue

            can_lock = self.can_lock_file(local_path, show_dialogs=False)
            if not can_lock:
                logger.warning(
                    'File "{}" cannot be locked and paths cannot be updated. Skipping ...'.format(local_path))
                continue

            if dcc.scene_name() != file_path:
                dcc.open_scene(file_path, save=True)

            dcc_parser = parser.Parser()
            valid_convert, updated_paths = dcc_parser.update_paths(local_path)
            updated_paths = utils.force_list(updated_paths)
            converted_paths.extend(updated_paths)

            if valid_convert and updated_paths and not skip_save:
                dcc.save_scene()

        converted_paths = list(set(converted_paths))
        if call_post_function and converted_paths:
            self._post_update_paths(files_updated=converted_paths)
Exemple #2
0
    def can_lock_file(self, file_path=None, show_dialogs=True):
        """
        Returns whether or not current opened DCC file can locked or not
        A file only can be locked if it is not already locked by other user.

        :param str or None file_path: Absolute local file path we want to check if can be locked or not. If not given,
            current DCC scene file will be locked.
        :param bool show_dialogs: Whether UI dialogs should appear or not.
        :return: True if the file can be locked by current user; False otherwise.
        :rtype: bool
        """

        artella_drive_client = self.get_client(show_dialogs=show_dialogs)
        if not artella_drive_client:
            return False

        if not file_path:
            file_path = dcc.scene_name()
        if not file_path:
            msg = 'File "{}" does not exists. Impossible to check if file can be locked or not!'.format(file_path)
            logger.warning(msg)
            if show_dialogs:
                dcc.show_warning(title='Artella - Failed to check lost status', message=msg)
            return False

        return artella_drive_client.can_lock_file(file_path)
Exemple #3
0
    def check_lock(self, file_path=None, show_dialogs=True):
        """
        Returns whether or not the given file is locked and whether or not current user is the one that has the file
        locked.

        :param str file_path: Absolute local file path to check lock status of
        :return: Returns a tuple with the following fields:
            - is_locked: True if the given file is locked; False otherwise
            - is_locked_by_me: True if the given file is locked by current user; False otherwise
            - locked_by_name: Name of the user that currently has the file locked
            - remote_record_found: Indicates whether the request relates to an existing remote file record or not
        :param bool show_dialogs: Whether UI dialogs should appear or not.
        :rtype: tuple(bool, bool, str)
        """

        artella_drive_client = self.get_client(show_dialogs=show_dialogs)
        if not artella_drive_client:
            return False, False, '', False

        if not file_path:
            file_path = dcc.scene_name()
        if not file_path:
            msg = 'File "{}" does not exists. Impossible to check lock status!'.format(file_path)
            logger.warning(msg)
            if show_dialogs:
                dcc.show_warning(title='Artella - Failed to check lost status', message=msg)
            return False, False, '', False

        return artella_drive_client.check_lock(file_path)
Exemple #4
0
    def unlock_file(self, file_path=None, show_dialogs=True, force=False):
        """
        Unlocks given file path in Artella Drive.

        :param str or None file_path: Absolute local file path we want to lock. If not given, current DCC scene file
            will be unlocked.
        :param bool show_dialogs: Whether UI dialogs should appear or not.
        :param bool force: Whether or not unlock operation should be done without asking the user
        :return: True if the lock operation was successful; False otherwise
        :rtype: bool
        """

        artella_drive_client = self.get_client(show_dialogs=show_dialogs)
        if not artella_drive_client:
            return False

        if not file_path:
            file_path = dcc.scene_name()
            if not file_path:
                msg = 'Unable to get file name, has it been created!?'
                logger.warning(msg)
                if show_dialogs:
                    dcc.show_warning(title='Artella - Failed to lock file', message=msg)
                return False

        if not file_path or not os.path.isfile(file_path):
            msg = 'File "{}" does not exists. Impossible to unlock.'.format(file_path)
            logger.warning(msg)
            if show_dialogs:
                dcc.show_error('Artella - Failed to unlock file', msg)
            return False

        result = True
        if show_dialogs and not force:
            msg = 'You have file "{}" locked in Artella.\nUnlock it now?'.format(os.path.basename(file_path))
            result = dcc.show_question('Artella - Unlock File', msg, cancel=False)
        if result is not True:
            return False

        uri_path = self.local_path_to_uri(file_path)
        valid_unlock = artella_drive_client.unlock_file(uri_path)
        if not valid_unlock:
            msg = 'Failed to unlock the file: "{}"\nTry unlocking it from the Artella ' \
                  'Drive area in the web browser'.format(os.path.basename(file_path))
            logger.warning(msg)
            if show_dialogs:
                dcc.show_error('Artella - Failed to unlock file', msg)
            return False

        return True
Exemple #5
0
    def is_artella_path(self, file_path=None):
        """
        Returns whether or not given file path is an Artella file path or not
        A path is considered to be an Artella path if the path is located inside the Artella project folder
        in the user machine

        :param str file_path: path to check. If not given, current DCC scene file path will be used
        :return: True if the given file path is an Artella path; False otherwise.
        :rtype: bool
        """

        artella_drive_client = self.get_client(show_dialogs=False)
        if not artella_drive_client:
            return False

        file_path = file_path or dcc.scene_name()

        return artella_drive_client.is_artella_path(file_path)
Exemple #6
0
    def lock_file(self, file_path=None, force=False, show_dialogs=True):
        """
        Locks given file path in Artella Drive.

        :param str or None file_path: Absolute local file path we want to lock. If not given, current DCC scene file
            will be locked.
        :param bool force: Whether to force the lock operation. If the file is locked by other user, the lock is break.
        :param bool show_dialogs: Whether UI dialogs should appear or not.
        :return: True if the lock operation was successful; False otherwise
        :rtype: bool
        """

        artella_drive_client = self.get_client(show_dialogs=show_dialogs)
        if not artella_drive_client:
            return False

        if not file_path:
            file_path = dcc.scene_name()
            if not file_path:
                msg = 'Unable to get file name, has it been created!?'
                logger.warning(msg)
                if show_dialogs:
                    dcc.show_warning(title='Artella - Failed to lock file', message=msg)
                return False

        if not file_path or not os.path.isfile(file_path):
            msg = 'File "{}" does not exists. Impossible to lock.'.format(file_path)
            logger.warning(msg)
            if show_dialogs:
                dcc.show_error('Artella - Failed to lock File', msg)
            return False

        file_version = artella_drive_client.file_current_version(file_path)
        if file_version <= 0:
            logger.info('File "{}" is not versioned yet. No need to lock.'.format(file_path))
            return True

        is_locked, is_locked_by_me, is_locked_by_name, remote_record_found = artella_drive_client.check_lock(file_path)
        can_write = os.access(file_path, os.W_OK)
        if not can_write and is_locked_by_me:
            logger.warning('Unable to determine local write permissions for file: "{}"'.format(file_path))
        if is_locked and not is_locked_by_me:
            msg = 'This file is locked by another user ({}). The file must be unlocked in order to save a new version.'
            logger.warning(msg)
            if show_dialogs:
                dcc.show_warning('Artella - Failed to lock file', msg)
            return False
        elif force or not is_locked:
            msg = '"{}" needs to be locked in order to save your file. ' \
                  'Would you like to lock the file now?'.format(os.path.basename(file_path))
            result = True
            if show_dialogs:
                result = dcc.show_question('Artella - lock file', msg, cancel=False)
            if result is not True:
                return False

        valid_lock = artella_drive_client.lock_file(file_path)
        if not valid_lock:
            msg = 'Failed to lock "{}"'.format(file_path)
            logger.warning(msg)
            dcc.show_warning('Artella - Failed to lock file', msg)
            return False

        return True
Exemple #7
0
    def make_new_version(self, file_path=None, comment=None, do_lock=False):
        """
        Uploads a new file/folder or a new version of current opened DCC scene file

        :param str file_path: Optional path of the file we want to create new version of. If not given, current
            opened DCC scene file path will be used.
        :param str comment: Optional comment to add to new version metadata. If not given, a generic message will be
            used.
        :param bool do_lock: Whether or not to force the lock of the file to make a new version. With new Artella
            version this is not mandatory.
        :return: True if the make new version operation is completed successfully; False otherwise.
        :rtype: bool
        """

        artella_drive_client = self.get_client()
        if not artella_drive_client:
            return False

        if not file_path:
            file_path = dcc.scene_name()
            if not file_path:
                msg = 'Please open a file before creating a new version'
                logger.warning(msg)
                return False

        file_path = utils.clean_path(file_path)

        can_lock = artella_drive_client.can_lock_file(file_path=file_path)
        if not can_lock:
            msg = 'Unable to lock file to make new version. File is already locked by other user.'
            dcc.show_error('File already locked by other user', msg)
            logger.error(msg)
            return False

        version_created = True

        comment = str(comment) if comment else 'New file version'

        file_version = artella_drive_client.file_current_version(file_path)
        if file_version is None:
            self.show_warning_message('Unable to retrieve version from current scene')
            return False

        next_version = file_version + 1

        is_locked, _, _, _ = artella_drive_client.check_lock(file_path)
        if not is_locked and do_lock:
            valid_lock = self.lock_file()
            if not valid_lock:
                self.show_error_message('Unable to lock file to make new version ({})'.format(next_version))
                return False

        logger.info('Saving current scene: {}'.format(file_path))
        valid_save = dcc.save_scene()
        if not valid_save:
            self.show_error_message('Unable to save current scene: "{}"'.format(file_path))
            version_created = False
        else:
            uri_path = self.local_path_to_uri(file_path)
            rsp = artella_drive_client.upload(uri_path, comment=comment)
            if rsp.get('error'):
                msg = 'Unable to upload a new version of file: "{}"\n{}\n{}'.format(
                    os.path.basename(file_path), rsp.get('url'), rsp.get('error'))
                self.show_error_message(msg)
                version_created = False

        if not is_locked and do_lock:
            self.unlock_file(show_dialogs=False)

        return version_created