Example #1
0
    def execute(self):
        if 'xclip' not in get_executables():
            self.fm.notify('xclip is not found.', bad=True)
            return

        arg = self.rest(1)
        if arg:
            if not os.path.isfile(arg):
                self.fm.notify('{} is not a file.'.format(arg))
                return
            file = File(arg)
        else:
            file = self.fm.thisfile
            if not file.is_file:
                self.fm.notify('{} is not a file.'.format(file.relative_path))
                return

        relative_path = file.relative_path
        cmd = ['xclip', '-selection', 'clipboard']
        if not file.is_binary():
            with open(file.path, 'rb') as fd:
                subprocess.check_call(cmd, stdin=fd)
        elif file.image:
            cmd += ['-t', file.mimetype, file.path]
            subprocess.check_call(cmd)
            self.fm.notify(
                'Content of {} is copied to x clipboard'.format(relative_path))
        else:
            self.fm.notify('{} is not an image file or a text file.'.format(
                relative_path))
Example #2
0
    def execute(self):
        import os
        import sys
        import tempfile
        from ranger.container.file import File
        from ranger.ext.shell_escape import shell_escape as esc
        py3 = sys.version_info[0] >= 3

        output = self.arg(1)
        if not self.arg(1):
            output = "output.pdf"

        # Create and edit the file list
        filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
        listfile = tempfile.NamedTemporaryFile(delete=False)
        listpath = listfile.name

        if py3:
            listfile.write("\n".join(filenames).encode("utf-8"))
        else:
            listfile.write("\n".join(filenames))
        listfile.close()
        self.fm.execute_file([File(listpath)], app='editor')
        listfile = open(listpath, 'r')
        # TODO check name and number consistance
        new_filenames = listfile.read().split("\n")
        listfile.close()
        os.unlink(listpath)
        listfilenames = " ".join((esc(f) for f in new_filenames))
        # if all(a == b for a, b in zip(filenames, new_filenames)):
        # self.fm.notify("No renaming to be done!")
        # return

        # TODO check output name

        # Generate script
        cmdfile = tempfile.NamedTemporaryFile()
        script_lines = []
        script_lines.append(
            "# This file will be executed when you close the editor.\n")
        script_lines.append(
            "# Please double-check everything, clear the file to abort.\n")
        script_lines.extend("pdfjam %s -o %s\n" % (listfilenames, esc(output)))
        script_content = "".join(script_lines)
        if py3:
            cmdfile.write(script_content.encode("utf-8"))
        else:
            cmdfile.write(script_content)
        cmdfile.flush()

        # Open the script and let the user review it, then check if the script
        # was modified by the user
        self.fm.execute_file([File(cmdfile.name)], app='editor')
        cmdfile.seek(0)
        script_was_edited = (script_content != cmdfile.read())

        # # Do the renaming
        self.fm.run(['/bin/sh', cmdfile.name], flags='w')
        cmdfile.close()
Example #3
0
    def execute(self):
        import subprocess
        from ranger.container.file import File
        from ranger.ext.get_executables import get_executables

        clipboard_managers = {
            'xclip': [
                ['xclip', '-selection', 'primary'],
                ['xclip', '-selection', 'clipboard'],
            ],
            'xsel': [
                ['xsel', '--primary'],
                ['xsel', '--clipboard'],
            ],
            'wl-copy': [
                ['wl-copy'],
            ],
            'pbcopy': [
                ['pbcopy'],
            ],
        }
        ordered_managers = ['pbcopy', 'wl-copy', 'xclip', 'xsel']
        executables = get_executables()
        for manager in ordered_managers:
            if manager in executables:
                clipboard_commands = clipboard_managers[manager]
                break
        else:
            self.fm.notify('Could not find a clipboard manager in the PATH.',
                           bad=True)
            return

        arg = self.rest(1)
        if arg:
            if not os.path.isfile(arg):
                self.fm.notify("'{}' is not a file.".format(arg), bad=True)
                return
            file = File(arg)
        else:
            file = self.fm.thisfile
            if not file.is_file:
                self.fm.notify("'{}' is not a file.".format(
                    file.relative_path),
                               bad=True)
                return

        if not file.is_binary():
            for command in clipboard_commands:
                with open(file.path, mode='r') as fd:
                    self.fm.execute_command(command,
                                            universal_newlines=True,
                                            stdin=fd)
            self.fm.notify(
                "The content of '{}' is copied to the clipboard.".format(
                    file.relative_path))
        else:
            self.fm.notify("'{}' is not a text file.".format(
                file.relative_path))
Example #4
0
    def execute(self):
        from ranger.container.file import File
        from os import access

        new_name = self.rest(1)

        tagged = {}
        old_name = self.fm.thisfile.relative_path
        for f in self.fm.tags.tags:
            if str(f).startswith(self.fm.thisfile.path):
                tagged[f] = self.fm.tags.tags[f]
                self.fm.tags.remove(f)

        if not new_name:
            return self.fm.notify('Syntax: rename <newname>', bad=True)

        if new_name == old_name:
            return

        if access(new_name, os.F_OK):
            return self.fm.notify("Can't rename: file already exists!",
                                  bad=True)

        if self.fm.rename(self.fm.thisfile, new_name):
            f = File(new_name)
            self.fm.thisdir.pointed_obj = f
            self.fm.thisfile = f
            for t in tagged:
                self.fm.tags.tags[t.replace(old_name, new_name)] = tagged[t]
                self.fm.tags.dump()
Example #5
0
 def ranger_bookmark_get(self, pid, env, args):
     try:
         bookmarks = dict((k,File(v)) for (k,v) in args[0].items() if os.path.exists(v))
         self.fm.bookmarks._set_dict(bookmarks, original=bookmarks)
         self.fm.ui.redraw_main_column()
     except Exception as ex:
         LOG.debug("""Unable to process "bookmark" command from squad: """ + str(ex))
Example #6
0
    def execute(self):
        import sys
        import tempfile
        from ranger.container.file import File
        from ranger.ext.shell_escape import shell_escape as esc
        py3 = sys.version > "3"

        # Create and edit the file list
        filenames = [f.basename for f in self.fm.thistab.get_selection()]
        listfile = tempfile.NamedTemporaryFile(delete=False)
        listpath = listfile.name

        if py3:
            listfile.write("\n".join(filenames).encode("utf-8"))
        else:
            listfile.write("\n".join(filenames))
        listfile.close()
        self.fm.execute_file([File(listpath)], app='editor')
        listfile = open(listpath, 'r')
        if py3:
            new_filenames = listfile.read().decode("utf-8").split("\n")
        else:
            new_filenames = listfile.read().split("\n")
        listfile.close()
        os.unlink(listpath)
        if all(a == b for a, b in zip(filenames, new_filenames)):
            self.fm.notify("No renaming to be done!")
            return

        # Generate and execute script
        cmdfile = tempfile.NamedTemporaryFile()
        cmdfile.write(
            b"# This file will be executed when you close the editor.\n")
        cmdfile.write(
            b"# Please double-check everything, clear the file to abort.\n")
        if py3:
            cmdfile.write("\n".join("mv -vi -- " + esc(old) + " " + esc(new) \
                for old, new in zip(filenames, new_filenames) \
                if old != new).encode("utf-8"))
        else:
            cmdfile.write("\n".join("mv -vi -- " + esc(old) + " " + esc(new) \
                for old, new in zip(filenames, new_filenames) if old != new))
        cmdfile.flush()
        self.fm.execute_file([File(cmdfile.name)], app='editor')
        self.fm.run(['/bin/sh', cmdfile.name], flags='w')
        cmdfile.close()
Example #7
0
def _get_object(path):
    if not isinstance(path, str):
        return path

    if os.path.isdir(path):
        return Directory(path)

    return File(path)
Example #8
0
 def edit_file(self, file=None):
     """Calls execute_file with the current file and label='editor'"""
     if file is None:
         file = self.thisfile
     elif isinstance(file, str):
         file = File(os.path.expanduser(file))
     if file is None:
         return
     self.execute_file(file, label='editor')
Example #9
0
    def execute(self):

        fname = self.fm.datapath(self.copy_buffer_filename)
        try:
            fobj = open(fname, "r")
        except OSError:
            return self.fm.notify("Cannot open %s" %
                                  (fname or self.copy_buffer_filename),
                                  bad=True)
        self.fm.copy_buffer = set(
            File(g) for g in fobj.read().split("\n") if exists(g))
        fobj.close()
        self.fm.ui.redraw_main_column()
Example #10
0
 def execute(self):
     from ranger.container.file import File
     from os.path import exists
     try:
         fname = self.fm.confpath(self.copy_buffer_filename)
         f = open(fname, 'r')
     except:
         return self.fm.notify("Cannot open %s" % \
                 (fname or self.copy_buffer_filename), bad=True)
     self.fm.copy_buffer = set(File(g) \
         for g in f.read().split("\n") if exists(g))
     f.close()
     self.fm.ui.redraw_main_column()
Example #11
0
 def execute(self):
     if not self.fm.settings["show_hidden"]:
         shell_command = "fd -d 1 | fzf"
     else:
         shell_command = "fd -d 1 -H | fzf"
     search = self.fm.execute_command(shell_command,
                                      universal_newlines=True,
                                      stdout=subprocess.PIPE)
     stdout, _ = search.communicate()
     if search.returncode == 0:
         result = os.path.abspath(stdout.rstrip("\n"))
         if os.path.isdir(result):
             self.fm.cd(result)
         elif os.path.isfile(result):
             self.fm.execute_file(File(result))
Example #12
0
 def execute(self):
     import tempfile
     from ranger.container.file import File
     from ranger.ext.shell_escape import shell_escape as esc
     cmdfile = tempfile.NamedTemporaryFile()
     script_files = ["#!/bin/bash"]
     script_files.extend(
         self.rest(1).format(fn=esc(f.relative_path))
         for f in self.fm.thistab.get_selection())
     script_files.append("echo FINISHED; read")
     cmdfile.write("\n".join(script_files))
     cmdfile.flush()
     self.fm.execute_file([File(cmdfile.name)], app='editor')
     self.fm.run(['/bin/sh', cmdfile.name], flags='w')
     cmdfile.close()
Example #13
0
    def execute(self):
        if self.arg(1):
            search_string = self.rest(1)
        else:
            self.fm.notify("Usage: fzf_rga_search_documents <search string>", bad=True)
            return

        import subprocess
        import os.path
        from ranger.container.file import File
        command="rga '%s' . --rga-adapters=pandoc,poppler | fzf +m | awk -F':' '{print $1}'" % search_string
        fzf = self.fm.execute_command(command, universal_newlines=True, stdout=subprocess.PIPE)
        stdout, stderr = fzf.communicate()
        if fzf.returncode == 0:
            fzf_file = os.path.abspath(stdout.rstrip('\n'))
            self.fm.execute_file(File(fzf_file))
Example #14
0
    def execute(self):
        if self.arg(1):
            search_string = self.rest(1)
        else:
            self.fm.notify("Usage: %s <search string>" % self.get_name(),
                           bad=True)
            return

        command = (self.searcher() + " '%s' " % search_string +
                   " | fzf +m | awk -F':' '{print $1}'")
        fzf = self.fm.execute_command(command,
                                      universal_newlines=True,
                                      stdout=subprocess.PIPE)
        stdout, _ = fzf.communicate()
        if fzf.returncode == 0:
            fzf_file = os.path.abspath(stdout.rstrip('\n'))
            self.fm.execute_file(File(fzf_file))
Example #15
0
    def execute(self):
        from ranger.container.file import File
        from os import access

        new_name = self.rest(1)

        if not new_name:
            return self.fm.notify('Syntax: rename <newname>', bad=True)

        if new_name == self.fm.thisfile.basename:
            return

        if access(new_name, os.F_OK):
            return self.fm.notify("Can't rename: file already exists!", bad=True)

        self.fm.rename(self.fm.thisfile, new_name)
        f = File(new_name)
        self.fm.thisdir.pointed_obj = f
        self.fm.thisfile = f
Example #16
0
    def execute(self):

        new_name = self.rest(1)

        if not new_name:
            return self.fm.notify("Syntax: rename <newname>", bad=True)

        if new_name == self.fm.thisfile.relative_path:
            return

        if access(new_name, os.F_OK):
            return self.fm.notify("Can't rename: file already exists!",
                                  bad=True)

        if self.fm.rename(self.fm.thisfile, new_name):
            file_new = File(new_name)
            self.fm.bookmarks.update_path(self.fm.thisfile.path, file_new)
            self.fm.tags.update_path(self.fm.thisfile.path, file_new.path)
            self.fm.thisdir.pointed_obj = file_new
            self.fm.thisfile = file_new
Example #17
0
    def execute(self):
        from ranger.container.file import File
        from os import access

        new_name = self.fm.thisfile.relative_path.replace(' ', '_')

        if new_name == self.fm.thisfile.relative_path:
            return None

        if access(new_name, os.F_OK):
            return self.fm.notify("Can't rename: file already exists!",
                                  bad=True)

        if self.fm.rename(self.fm.thisfile, new_name):
            file_new = File(new_name)
            self.fm.bookmarks.update_path(self.fm.thisfile.path, file_new)
            self.fm.tags.update_path(self.fm.thisfile.path, file_new.path)
            self.fm.thisdir.pointed_obj = file_new
            self.fm.thisfile = file_new

        return None
Example #18
0
    def execute(self):
        from ranger.container.file import File
        from os import access

        new_name = self.rest(1)

        tagged = {}
        old_name = self.fm.thisfile.relative_path
        for f in self.fm.tags.tags:
            if str(f).startswith(self.fm.thisfile.path):
                tagged[f] = self.fm.tags.tags[f]
                self.fm.tags.remove(f)

        if not new_name:
            return self.fm.notify('Syntax: rename <newname>', bad=True)

        if new_name == old_name:
            return

        if access(new_name, os.F_OK):
            return self.fm.notify("Can't rename: file already exists!",
                                  bad=True)

        if self.fm.rename(self.fm.thisfile, new_name):
            f = File(new_name)
            # Update bookmarks that were pointing on the previous name
            obsoletebookmarks = [
                b for b in self.fm.bookmarks if b[1].path == self.fm.thisfile
            ]
            if obsoletebookmarks:
                for key, _ in obsoletebookmarks:
                    self.fm.bookmarks[key] = f
                self.fm.bookmarks.update_if_outdated()

            self.fm.thisdir.pointed_obj = f
            self.fm.thisfile = f
            for t in tagged:
                self.fm.tags.tags[t.replace(old_name, new_name)] = tagged[t]
                self.fm.tags.dump()
Example #19
0
 def execute(self):
     """Call when the command is executed."""
     arg = self.rest(1)
     if arg:
         if not os.path.isfile(arg):
             self.fm.notify("{} is not a file.".format(arg))
             return
         file = File(arg)
     else:
         file = self.fm.thisfile
         if not file.is_file:
             self.fm.notify("{} is not a file.".format(file.relative_path))
             return
     relative_path = file.relative_path
     self.fm.notify(f"File: {relative_path}")
     upload_command = [
         "python",
         "/home/lovinator/Repository/screenshot-helper/main.py",
         "--upload",
         arg,
     ]
     subprocess.check_call(upload_command)
     self.fm.notify("Uploaded!")
Example #20
0
    def load_bit_by_bit(self):
        """An iterator that loads a part on every next() call

        Returns a generator which load a part of the directory
        in each iteration.
        """

        self.loading = True
        self.percent = 0
        self.load_if_outdated()

        basename_is_rel_to = self.path if self.flat else None

        try:  # pylint: disable=too-many-nested-blocks
            if self.runnable:
                yield
                mypath = self.path

                self.mount_path = mount_path(mypath)

                def ignore_files():
                    directory = expanduser("~")
                    files = []
                    for filename in os.listdir(directory):
                        if filename.startswith(
                                "ranger_") and filename.endswith(".txt"):
                            with open(os.path.join(directory, filename),
                                      'r') as f:
                                files += f.read().strip().split("\n")
                    return list(set(files))

                if self.flat:
                    filelist = []
                    for dirpath, dirnames, filenames in walklevel(
                            mypath, self.flat):
                        dirlist = [
                            os.path.join("/", dirpath, d) for d in dirnames
                            if self.flat == -1 or
                            (dirpath.count(os.path.sep) -
                             mypath.count(os.path.sep)) <= self.flat
                        ]
                        filelist += dirlist
                        filelist += [
                            os.path.join("/", dirpath, f) for f in filenames
                        ]
                    filenames = filelist
                    filenames = [
                        f for f in filenames if not f in ignore_files()
                    ]
                    self.load_content_mtime = mtimelevel(mypath, self.flat)
                else:
                    filelist = os.listdir(mypath)
                    filenames = [
                        mypath + (mypath == '/' and fname or '/' + fname)
                        for fname in filelist
                    ]
                    filenames = [
                        f for f in filenames if not f in ignore_files()
                    ]
                    self.load_content_mtime = os.stat(mypath).st_mtime

                if self.cumulative_size_calculated:
                    # If self.content_loaded is true, this is not the first
                    # time loading.  So I can't really be sure if the
                    # size has changed and I'll add a "?".
                    if self.content_loaded:
                        if self.fm.settings.autoupdate_cumulative_size:
                            self.look_up_cumulative_size()
                        else:
                            self.infostring = ' %s' % human_readable(
                                self.size, separator='? ')
                    else:
                        self.infostring = ' %s' % human_readable(self.size)
                else:
                    self.size = len(filelist)
                    self.infostring = ' %d' % self.size
                if self.is_link:
                    self.infostring = '->' + self.infostring

                yield

                marked_paths = [obj.path for obj in self.marked_items]

                files = []
                disk_usage = 0

                has_vcschild = False
                for name in filenames:
                    try:
                        file_lstat = os_lstat(name)
                        if file_lstat.st_mode & 0o170000 == 0o120000:
                            file_stat = os_stat(name)
                        else:
                            file_stat = file_lstat
                    except OSError:
                        file_lstat = None
                        file_stat = None
                    if file_lstat and file_stat:
                        stats = (file_stat, file_lstat)
                        is_a_dir = file_stat.st_mode & 0o170000 == 0o040000
                    else:
                        stats = None
                        is_a_dir = False

                    if is_a_dir:
                        item = self.fm.get_directory(
                            name,
                            preload=stats,
                            path_is_abs=True,
                            basename_is_rel_to=basename_is_rel_to)
                        item.load_if_outdated()
                        if self.flat:
                            item.relative_path = os.path.relpath(
                                item.path, self.path)
                        else:
                            item.relative_path = item.basename
                        item.relative_path_lower = item.relative_path.lower()
                        if item.vcs and item.vcs.track:
                            if item.vcs.is_root_pointer:
                                has_vcschild = True
                            else:
                                item.vcsstatus = \
                                    item.vcs.rootvcs.status_subpath(  # pylint: disable=no-member
                                        os.path.join(self.realpath, item.basename),
                                        is_directory=True,
                                    )
                    else:
                        item = File(name,
                                    preload=stats,
                                    path_is_abs=True,
                                    basename_is_rel_to=basename_is_rel_to)
                        item.load()
                        disk_usage += item.size
                        if self.vcs and self.vcs.track:
                            item.vcsstatus = \
                                self.vcs.rootvcs.status_subpath(  # pylint: disable=no-member
                                    os.path.join(self.realpath, item.basename))

                    files.append(item)
                    self.percent = 100 * len(files) // len(filenames)
                    yield
                self.has_vcschild = has_vcschild
                self.disk_usage = disk_usage

                self.filenames = filenames
                self.files_all = files

                self._clear_marked_items()
                for item in self.files_all:
                    if item.path in marked_paths:
                        item.mark_set(True)
                        self.marked_items.append(item)
                    else:
                        item.mark_set(False)

                self.sort()

                if files:
                    if self.pointed_obj is not None:
                        self.sync_index()
                    else:
                        self.move(to=0)
            else:
                self.filenames = None
                self.files_all = None
                self.files = None

            self.cycle_list = None
            self.content_loaded = True
            self.last_update_time = time()
            self.correct_pointer()

        finally:
            self.loading = False
            self.fm.signal_emit("finished_loading_dir", directory=self)
            if self.vcs:
                self.fm.ui.vcsthread.process(self)
Example #21
0
    def load_bit_by_bit(self):
        """An iterator that loads a part on every next() call

        Returns a generator which load a part of the directory
        in each iteration.
        """

        self.loading = True
        self.percent = 0
        self.load_if_outdated()

        basename_is_rel_to = self.path if self.flat else None

        try:
            if self.runnable:
                yield
                mypath = self.path

                self.mount_path = mount_path(mypath)

                if self.flat:
                    filelist = []
                    for dirpath, dirnames, filenames in walklevel(
                            mypath, self.flat):
                        dirlist = [
                            os.path.join("/", dirpath, d) for d in dirnames
                            if self.flat == -1 or dirpath.count(os.path.sep) -
                            mypath.count(os.path.sep) <= self.flat
                        ]
                        filelist += dirlist
                        filelist += [
                            os.path.join("/", dirpath, f) for f in filenames
                        ]
                    filenames = filelist
                    self.load_content_mtime = mtimelevel(mypath, self.flat)
                else:
                    filelist = os.listdir(mypath)
                    filenames = [
                        mypath + (mypath == '/' and fname or '/' + fname)
                        for fname in filelist
                    ]
                    self.load_content_mtime = os.stat(mypath).st_mtime

                if self._cumulative_size_calculated:
                    # If self.content_loaded is true, this is not the first
                    # time loading.  So I can't really be sure if the
                    # size has changed and I'll add a "?".
                    if self.content_loaded:
                        if self.fm.settings.autoupdate_cumulative_size:
                            self.look_up_cumulative_size()
                        else:
                            self.infostring = ' %s' % human_readable(
                                self.size, separator='? ')
                    else:
                        self.infostring = ' %s' % human_readable(self.size)
                else:
                    self.size = len(filelist)
                    self.infostring = ' %d' % self.size
                if self.is_link:
                    self.infostring = '->' + self.infostring

                yield

                marked_paths = [obj.path for obj in self.marked_items]

                files = []
                disk_usage = 0

                if self.settings.vcs_aware:
                    self.has_vcschild = False
                    self.load_vcs(None)

                for name in filenames:
                    try:
                        file_lstat = os_lstat(name)
                        if file_lstat.st_mode & 0o170000 == 0o120000:
                            file_stat = os_stat(name)
                        else:
                            file_stat = file_lstat
                        stats = (file_stat, file_lstat)
                        is_a_dir = file_stat.st_mode & 0o170000 == 0o040000
                    except:
                        stats = None
                        is_a_dir = False
                    if is_a_dir:
                        if self.flat:
                            item = Directory(
                                name,
                                preload=stats,
                                path_is_abs=True,
                                basename_is_rel_to=basename_is_rel_to)
                            item.load()
                        else:
                            try:
                                item = self.fm.get_directory(name)
                                item.load_if_outdated()
                            except:
                                item = Directory(name,
                                                 preload=stats,
                                                 path_is_abs=True)
                                item.load()
                    else:
                        item = File(name,
                                    preload=stats,
                                    path_is_abs=True,
                                    basename_is_rel_to=basename_is_rel_to)
                        item.load()
                        disk_usage += item.size

                    # Load vcs data
                    if self.settings.vcs_aware:
                        item.load_vcs(self)
                        if item.vcs_enabled:
                            self.has_vcschild = True

                    files.append(item)
                    self.percent = 100 * len(files) // len(filenames)
                    yield
                self.disk_usage = disk_usage
                self.vcs_outdated = False

                self.filenames = filenames
                self.files_all = files

                self._clear_marked_items()
                for item in self.files_all:
                    if item.path in marked_paths:
                        item._mark(True)
                        self.marked_items.append(item)
                    else:
                        item._mark(False)

                self.sort()

                if files:
                    if self.pointed_obj is not None:
                        self.sync_index()
                    else:
                        self.move(to=0)
            else:
                self.filenames = None
                self.files_all = None
                self.files = None

            self.cycle_list = None
            self.content_loaded = True
            self.last_update_time = time()
            self.correct_pointer()

        finally:
            self.loading = False
            self.fm.signal_emit("finished_loading_dir", directory=self)
Example #22
0
 def ranger_copy_get(self, pid, env, args):
     try:
         self.fm.copy_buffer = set(File(g) for g in args if os.path.exists(g))
         self.fm.ui.redraw_main_column()
     except Exception as ex:
         LOG.debug("""Unable to process "copy" command from squad: """ + str(ex))
Example #23
0
    def execute(self):
        import sys
        import tempfile
        from ranger.container.file import File
        from ranger.ext.shell_escape import shell_escape as esc
        py3 = sys.version_info[0] >= 3

        # Create and edit the file list
        filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
        listfile = tempfile.NamedTemporaryFile(delete=False)
        listpath = listfile.name

        if py3:
            listfile.write("\n".join(filenames).encode("utf-8"))
        else:
            listfile.write("\n".join(filenames))
        listfile.close()
        self.fm.execute_file([File(listpath)], app='editor')
        listfile = open(listpath, 'r')
        new_filenames = listfile.read().split("\n")
        listfile.close()
        os.unlink(listpath)
        if all(a == b for a, b in zip(filenames, new_filenames)):
            self.fm.notify("No renaming to be done!")
            return

        # Generate script
        cmdfile = tempfile.NamedTemporaryFile()
        script_lines = []
        script_lines.append(
            "# This file will be executed when you close the editor.\n")
        script_lines.append(
            "# Please double-check everything, clear the file to abort.\n")
        script_lines.extend("mv -vi -- %s %s\n" % (esc(old), esc(new)) \
                for old, new in zip(filenames, new_filenames) if old != new)
        script_content = "".join(script_lines)
        if py3:
            cmdfile.write(script_content.encode("utf-8"))
        else:
            cmdfile.write(script_content)
        cmdfile.flush()

        # Open the script and let the user review it, then check if the script
        # was modified by the user
        self.fm.execute_file([File(cmdfile.name)], app='editor')
        cmdfile.seek(0)
        script_was_edited = (script_content != cmdfile.read())

        # Do the renaming
        self.fm.run(['/bin/sh', cmdfile.name], flags='w')
        cmdfile.close()

        # Retag the files, but only if the script wasn't changed during review,
        # because only then we know which are the source and destination files.
        if not script_was_edited:
            tags_changed = False
            for old, new in zip(filenames, new_filenames):
                if old != new:
                    oldpath = self.fm.thisdir.path + '/' + old
                    newpath = self.fm.thisdir.path + '/' + new
                    if oldpath in self.fm.tags:
                        old_tag = self.fm.tags.tags[oldpath]
                        self.fm.tags.remove(oldpath)
                        self.fm.tags.tags[newpath] = old_tag
                        tags_changed = True
            if tags_changed:
                self.fm.tags.dump()
        else:
            fm.notify("files have not been retagged")
Example #24
0
    def execute(self):
        from ranger.container.file import File  # pylint: disable=import-outside-toplevel
        # pylint: disable=import-outside-toplevel
        from ranger.ext.shell_escape import shell_escape as esc

        editor = os.getenv('EDITOR')
        if not editor:
            editor = 'nvim'

        # Create and edit the file list
        filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
        with tempfile.NamedTemporaryFile(delete=False) as listfile:
            listpath = listfile.name
            listfile.write('\n'.join(filenames).encode(
                encoding='utf-8', errors='surrogateescape'))
        self.fm.execute_file([File(listpath)], app='{}'.format(editor))
        with open(listpath, 'r', encoding='utf-8',
                  errors='surrogateescape') as listfile:
            new_filenames = listfile.read().split("\n")
        os.unlink(listpath)
        if all(a == b for a, b in zip(filenames, new_filenames)):
            self.fm.notify('No renaming to be done!')
            return

        # Generate script
        with tempfile.NamedTemporaryFile() as cmdfile:
            script_lines = []
            script_lines.append(
                '# This file will be executed when you close the editor.')
            script_lines.append(
                '# Please double-check everything, clear the file to abort.')
            new_dirs = []
            for old, new in zip(filenames, new_filenames):
                if old != new:
                    basepath, _ = os.path.split(new)
                    if (basepath and basepath not in new_dirs
                            and not os.path.isdir(basepath)):
                        script_lines.append(
                            'mkdir -vp -- {dir}'.format(dir=esc(basepath)))
                        new_dirs.append(basepath)
                    script_lines.append('mv -vi -- {old} {new}'.format(
                        old=esc(old), new=esc(new)))
            # Make sure not to forget the ending newline
            script_content = '\n'.join(script_lines) + '\n'
            cmdfile.write(
                script_content.encode(encoding='utf-8',
                                      errors='surrogateescape'))
            cmdfile.flush()

            # Open the script and let the user review it, then check if the
            # script was modified by the user
            self.fm.execute_file([File(cmdfile.name)], app='{}'.format(editor))
            cmdfile.seek(0)
            new_content = cmdfile.read()
            script_was_edited = (script_content != new_content)

            # Do the renaming
            self.fm.run(['/bin/sh', cmdfile.name], flags='w')

            _parse_cmd_and_move_buf(new_content)

        # Retag the files, but only if the script wasn't changed during review,
        # because only then we know which are the source and destination files.
        if not script_was_edited:
            tags_changed = False
            for old, new in zip(filenames, new_filenames):
                if old != new:
                    oldpath = self.fm.thisdir.path + '/' + old
                    newpath = self.fm.thisdir.path + '/' + new
                    if oldpath in self.fm.tags:
                        old_tag = self.fm.tags.tags[oldpath]
                        self.fm.tags.remove(oldpath)
                        self.fm.tags.tags[newpath] = old_tag
                        tags_changed = True
            if tags_changed:
                self.fm.tags.dump()
        else:
            self.fm.notify('files have not been retagged')
Example #25
0
    def load_bit_by_bit(self):
        """An iterator that loads a part on every next() call

        Returns a generator which load a part of the directory
        in each iteration.
        """

        self.loading = True
        self.percent = 0
        self.load_if_outdated()

        basename_is_rel_to = self.path if self.flat else None

        try:  # pylint: disable=too-many-nested-blocks
            if self.runnable:
                yield
                mypath = self.path

                self.mount_path = mount_path(mypath)

                if self.flat:
                    filelist = []
                    for dirpath, dirnames, filenames in walklevel(mypath, self.flat):
                        dirlist = [
                            os.path.join("/", dirpath, d)
                            for d in dirnames
                            if self.flat == -1 or
                            (dirpath.count(os.path.sep) - mypath.count(os.path.sep)) <= self.flat
                        ]
                        filelist += dirlist
                        filelist += [os.path.join("/", dirpath, f) for f in filenames]
                    filenames = filelist
                    self.load_content_mtime = mtimelevel(mypath, self.flat)
                else:
                    filelist = os.listdir(mypath)
                    filenames = [mypath + (mypath == '/' and fname or '/' + fname)
                                 for fname in filelist]
                    self.load_content_mtime = os.stat(mypath).st_mtime

                if self.cumulative_size_calculated:
                    # If self.content_loaded is true, this is not the first
                    # time loading.  So I can't really be sure if the
                    # size has changed and I'll add a "?".
                    if self.content_loaded:
                        if self.fm.settings.autoupdate_cumulative_size:
                            self.look_up_cumulative_size()
                        else:
                            self.infostring = ' %s' % human_readable(
                                self.size, separator='? ')
                    else:
                        self.infostring = ' %s' % human_readable(self.size)
                else:
                    self.size = len(filelist)
                    self.infostring = ' %d' % self.size
                if self.is_link:
                    self.infostring = '->' + self.infostring

                yield

                marked_paths = [obj.path for obj in self.marked_items]

                files = []
                disk_usage = 0

                has_vcschild = False
                for name in filenames:
                    try:
                        file_lstat = os_lstat(name)
                        if file_lstat.st_mode & 0o170000 == 0o120000:
                            file_stat = os_stat(name)
                        else:
                            file_stat = file_lstat
                    except OSError:
                        file_lstat = None
                        file_stat = None
                    if file_lstat and file_stat:
                        stats = (file_stat, file_lstat)
                        is_a_dir = file_stat.st_mode & 0o170000 == 0o040000
                    else:
                        stats = None
                        is_a_dir = False

                    if is_a_dir:
                        item = self.fm.get_directory(name, preload=stats, path_is_abs=True,
                                                     basename_is_rel_to=basename_is_rel_to)
                        item.load_if_outdated()
                        if self.flat:
                            item.relative_path = os.path.relpath(item.path, self.path)
                        else:
                            item.relative_path = item.basename
                        item.relative_path_lower = item.relative_path.lower()
                        if item.vcs and item.vcs.track:
                            if item.vcs.is_root_pointer:
                                has_vcschild = True
                            else:
                                item.vcsstatus = \
                                    item.vcs.rootvcs.status_subpath(  # pylint: disable=no-member
                                        os.path.join(self.realpath, item.basename),
                                        is_directory=True,
                                    )
                    else:
                        item = File(name, preload=stats, path_is_abs=True,
                                    basename_is_rel_to=basename_is_rel_to)
                        item.load()
                        disk_usage += item.size
                        if self.vcs and self.vcs.track:
                            item.vcsstatus = \
                                self.vcs.rootvcs.status_subpath(  # pylint: disable=no-member
                                    os.path.join(self.realpath, item.basename))

                    files.append(item)
                    self.percent = 100 * len(files) // len(filenames)
                    yield
                self.has_vcschild = has_vcschild
                self.disk_usage = disk_usage

                self.filenames = filenames
                self.files_all = files

                self._clear_marked_items()
                for item in self.files_all:
                    if item.path in marked_paths:
                        item.mark_set(True)
                        self.marked_items.append(item)
                    else:
                        item.mark_set(False)

                self.sort()

                if files:
                    if self.pointed_obj is not None:
                        self.sync_index()
                    else:
                        self.move(to=0)
            else:
                self.filenames = None
                self.files_all = None
                self.files = None

            self.cycle_list = None
            self.content_loaded = True
            self.last_update_time = time()
            self.correct_pointer()

        finally:
            self.loading = False
            self.fm.signal_emit("finished_loading_dir", directory=self)
            if self.vcs:
                self.fm.ui.vcsthread.process(self)