예제 #1
0
def prepare_mod_directory(mod_full_path, check_writable=True):
    """Prepare the mod with the correct permissions, etc...
    This should make sure the parent directories are present, the mod directory
    is either not existing or it is present and has no broken symlinks.

    Right now, there is a lot of duplicate code in here, that will hopefully be
    refactored in the future, after the other features are implemented.
    """
    # TODO: Simplify all the calls and remove duplicate code
    parent_location = os.path.dirname(mod_full_path)

    # Ensure the base directory exists
    ensure_directory_exists(parent_location)
    set_node_read_write(parent_location)

    # If mod directory exists, check if it's valid
    if os.path.lexists(mod_full_path):
        if os.path.isdir(mod_full_path):
            remove_broken_junction(mod_full_path)
        else:
            # If it's not a directory, remove it because we need a dir here
            os.unlink(mod_full_path)

    if os.path.lexists(mod_full_path):
        if check_writable:
            # Read-write everything
            ensure_directory_structure_is_correct(mod_full_path)

    else:
        if not paths.is_dir_writable(parent_location):
            error_message = get_admin_error('directory is not writable',
                                            parent_location)
            raise AdminRequiredError(error_message)
예제 #2
0
    def select_success(self, path):
        Logger.info('Modlist: User selected the directory: {}'.format(path))

        if not os.path.isdir(path):
            return 'Not a directory or unreadable:\n{}'.format(path)

        if not is_dir_writable(path):
            return 'Directory {} is not writable'.format(path)

        # Prevent idiot-loops (seriously, people doing this are idiots!)
        already_used_by = path_already_used_for_mod(path, self.owner.all_existing_mods)
        settings = kivy.app.App.get_running_app().settings
        if not path_can_be_a_mod(path, settings.get('launcher_moddir')) or \
            (already_used_by and already_used_by != self.mod.foldername):
            message = textwrap.dedent('''
                Really???

                You're now selecting the location where {} is ALREADY installed and you've chosen:
                {}

                You realize that selecting that directory will cause EVERYTHING
                inside that is not part of that mod to be DELETED?

                Think twice next time!
            ''').format(self.mod.foldername, path)
            return message

        if casefold(path) == casefold(self.mod.get_full_path()):
            Logger.info('select_success: Selected directory is the current one. Ignoring...')
            return

        self.set_new_path(path)
예제 #3
0
    def _fbrowser_success(self, path):
        if not self.is_directory_ok(path):
            return 'Not a directory or unreadable:\n{}'.format(path)

        if not is_dir_writable(path):
            return 'Directory {} is not writable'.format(path)

        self.dismiss()
        self.on_selection('search', path)
예제 #4
0
def ensure_directory_structure_is_correct(mod_directory):
    """Ensures all the files in the mod's directory have the write bit set and
    there are no broken Junctions nor Symlinks in the directory structure.
    Useful if some external tool has set them to read-only.
    """

    Logger.info(
        'Torrent_utils: Checking read-write file access in directory: {}.'.
        format(mod_directory))

    set_node_read_write(mod_directory)
    _replace_broken_junction_with_directory(mod_directory)

    if not paths.is_dir_writable(mod_directory):
        error_message = get_admin_error('directory is not writable',
                                        mod_directory)
        raise AdminRequiredError(error_message)

    for (dirpath, dirnames, filenames) in walker.walk(mod_directory):
        # Needs to check the dirnames like this because if a child directory is
        # a broken junction, it's never going to be used as dirpath
        for node_name in dirnames:
            node_path = os.path.join(dirpath, node_name)
            Logger.info('Torrent_utils: Checking node: {}'.format(node_path))

            set_node_read_write(node_path)
            _replace_broken_junction_with_directory(node_path)

            if not paths.is_dir_writable(node_path):
                error_message = get_admin_error('directory is not writable',
                                                node_path)
                raise AdminRequiredError(error_message)

        for node_name in filenames:
            node_path = os.path.join(dirpath, node_name)
            Logger.info('Torrent_utils: Checking node: {}'.format(node_path))

            set_node_read_write(node_path)

            if not paths.is_file_writable(node_path):
                error_message = get_admin_error('file is not writable',
                                                node_path)
                raise AdminRequiredError(error_message)
예제 #5
0
def require_admin_privileges():
    """Check if the process can overwrite the executable being run or if it needs extra priviledges.
    For now, this will just get the directory of the executable and try to
    create a dummy file in there. We assume the executable will have the same
    permissions as every file in the same directory.
    If a dummy file cannot be created, it means we probably need administrator
    provileges to perform the substitution.
    """

    my_executable_dir = os.path.dirname(get_external_executable())
    Logger.info('Autoupdater: executable dir: {}'.format(my_executable_dir))
    dir_is_writable = paths.is_dir_writable(my_executable_dir)
    Logger.info('Autoupdater: dir_is_writable: {}'.format(dir_is_writable))
    return not dir_is_writable
예제 #6
0
    def _fbrowser_success(self, path):
        if not os.path.isdir(path):
            Logger.error('PrefScreen: path is not a dir: ' + path)
            return 'The selected path does not point to a directory'.format(path)

        if not is_dir_writable(path):
            Logger.error('PrefScreen: Directory {} is not writable'.format(path))
            return 'Directory {} is not writable'.format(path)

        # normalize path
        path = os.path.abspath(path)
        Logger.info('PrefScreen: Got filechooser ok event: ' + path)

        # this will save automatically
        self.settings.set('launcher_moddir', path)

        self.view.ids.mods_options.ids.path_text_input.text = self.settings.get('launcher_moddir')