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)
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)
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)
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
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)
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
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