コード例 #1
0
ファイル: delete_command.py プロジェクト: jcjgraf/vimiv-qt
def delete(paths: List[str]) -> None:
    """Move one or more images to the trash directory.

    **syntax:** ``:delete path [path ...]``

    positional arguments:
        * ``paths``: The path(s) to the images to delete.

    .. note:: This only deletes images, not any other path(s).
    """
    _last_deleted.clear()
    images = [path for path in paths if files.is_image(path)]
    if not images:
        raise api.commands.CommandError("No images to delete")
    failed_images = []
    for filename in images:
        try:
            trash_filename = trash_manager.delete(filename)
            _last_deleted.append(os.path.basename(trash_filename))
        except OSError:
            failed_images.append(filename)

    n_fail = len(failed_images)
    n_success = len(images) - n_fail
    fail_msg = f"Failed to delete {', '.join(failed_images)}" if n_fail > 0 else ""
    succ_msg = f"Deleted {n_success} images" if n_success > 0 else ""

    if fail_msg:
        log.warning(f"{succ_msg + ' but ' if succ_msg else ''}{fail_msg}")
    elif succ_msg:
        log.info(succ_msg)
コード例 #2
0
    def mark(self, paths: List[str], action: Action = Action.Toggle) -> None:
        """Mark one or more paths.

        **syntax:** ``:mark path [path ...] [--action=ACTION]``

        .. hint:: ``:mark %`` marks the current path.

        positional arguments:
            * ``paths``: The path(s) to mark.

        optional arguments:
            * ``--action``: One of toggle/mark/unmark. Toggle, the default, inverses the
              mark status of the path(s). Mark forces marking while unmark forces
              removing the mark.
        """
        _logger.debug("Calling %s on %d paths", action.value, len(paths))
        function = self._actions[action]
        for path in paths:
            if files.is_image(path):
                try:
                    function(path)
                except ValueError:
                    _logger.debug("Calling %s on '%s' failed", action.value,
                                  path)
        self.markdone.emit()
コード例 #3
0
def _load_single(path: str) -> None:
    """Populate list of paths in same directory for single path."""
    if path in _paths:
        goto(_paths.index(path) + 1)  # goto is indexed from 1
    elif path not in api.working_directory.handler.images and files.is_image(path):
        _load_paths([path, *api.working_directory.handler.images], path)
    else:
        _load_paths(api.working_directory.handler.images, path)
コード例 #4
0
ファイル: test_files.py プロジェクト: kaldown/vimiv-qt
def test_tar_gz_not_an_image(tmpdir):
    """Test if is_image for a tar.gz returns False.

    The default implementation of QImageReader.canRead returns True which is not
    correct.
    """
    outfile = str(tmpdir.join("dummy.tar.gz"))
    indirectory = str(tmpdir.mkdir("indir"))
    with tarfile.open(outfile, mode="w:gz") as tar:
        tar.add(indirectory, arcname=os.path.basename(indirectory))
    assert files.is_image(outfile) is False
コード例 #5
0
def test_tar_gz_not_an_image(tmp_path):
    """Test if is_image for a tar.gz returns False.

    The default implementation of QImageReader.canRead returns True which is not
    correct.
    """
    tarpath = tmp_path / "dummy.tar.gz"
    tarred_directory = tmp_path / "indir"
    tarred_directory.mkdir()
    with tarfile.open(tarpath, mode="w:gz") as tar:
        tar.add(tarred_directory, arcname=tarred_directory.name)
    assert files.is_image(str(tarpath)) is False
コード例 #6
0
    def mark(self, paths: List[str]) -> None:
        """Mark one or more paths.

        **syntax:** ``:mark path [path ...]``

        If a path is currently marked, it is unmarked instead.

        .. hint:: ``:mark %`` marks the current path.

        positional arguments:
            * ``paths``: The path(s) to mark.
        """
        for path in (path for path in paths if files.is_image(path)):
            self._toggle_mark(path)
コード例 #7
0
ファイル: _modules.py プロジェクト: jcjgraf/vimiv-qt
def rename(
    paths: List[str],
    base: str,
    start: int = 1,
    separator: str = "_",
    overwrite: bool = False,
    skip_image_check: bool = False,
) -> None:
    """Rename images with a common base.

    **syntax:** ``:rename path [path ...] base [--start=INDEX] [--separator=SEPARATOR]
    [--overwrite] [--skip-image-check]``

    Example::
        ``:rename * identifier`` would rename all images in the filelist to
        ``identifier_001``, ``identifier_002``, ..., ``identifier_NNN``.

    positional arguments:
        * ``paths``: The path(s) to rename.
        * ``base``: Base name to use for numbering.

    optional arguments:
        * ``--start``: Index to start numbering with. Default: 1.
        * ``--separator``: Separator between base and numbers. Default: '_'.
        * ``--overwrite``: Overwrite existing paths when renaming.
        * ``--skip-image-check``: Do not check if all renamed paths are images.
    """
    paths = [
        path for path in paths if files.is_image(path) or skip_image_check
    ]
    if not paths:
        raise api.commands.CommandError("No paths to rename")
    marked = []
    for i, path in enumerate(paths, start=start):
        _, extension = os.path.splitext(path)
        dirname = os.path.dirname(path)
        basename = f"{base}{separator}{i:03d}{extension}"
        outfile = os.path.join(dirname, basename)
        if os.path.exists(outfile) and not overwrite:
            log.warning(
                "Outfile '%s' exists, skipping. To overwrite add '--overwrite'.",
                outfile,
            )
        else:
            _logger.debug("%s -> %s", path, outfile)
            os.rename(path, outfile)
            if path in api.mark.paths:  # Keep mark status of the renamed path
                marked.append(outfile)
    api.mark.mark(marked)
コード例 #8
0
ファイル: _file_handler.py プロジェクト: kaldown/vimiv-qt
 def _write(self):
     """Write pixmap to disk."""
     # Get pixmap type
     _, ext = os.path.splitext(self._path)
     # First create temporary file and then move it to avoid race conditions
     handle, filename = tempfile.mkstemp(dir=os.getcwd(), suffix=ext)
     os.close(handle)
     self._pixmap.save(filename)
     # Copy exif info from original file to new file
     imutils.exif.copy_exif(self._original_path, filename)
     os.rename(filename, self._path)
     # Check if valid image was created
     if not os.path.isfile(self._path):
         raise WriteError("File not written, unknown exception")
     if not files.is_image(self._path):
         os.remove(self._path)
         raise WriteError("No valid image written. Is the extention valid?")
コード例 #9
0
ファイル: delete_command.py プロジェクト: jkrass1/vimiv-qt
def delete(paths: List[str]) -> None:
    """Move one or more images to the trash directory.

    **syntax:** ``:delete path [path ...]``

    positional arguments:
        * ``paths``: The path(s) to the images to delete.

    .. note:: This only deletes images, not any other path(s).
    """
    _last_deleted.clear()
    images = [path for path in paths if files.is_image(path)]
    if not images:
        raise api.commands.CommandError("No images to delete")
    for filename in images:
        trash_filename = trash_manager.delete(filename)
        _last_deleted.append(os.path.basename(trash_filename))
    n_images = len(images)
    if n_images > 1:
        log.info("Deleted %d images", n_images)
コード例 #10
0
ファイル: delete_command.py プロジェクト: karlch/vimiv-qt
def delete(paths: List[str], ask: bool = False) -> None:
    """Move one or more images to the trash directory.

    **syntax:** ``:delete path [path ...]``

    positional arguments:
        * ``paths``: The path(s) to the images to delete.

    optional arguments:
        * ``--ask``: Prompt for confirmation before deleting the images.

    .. note:: This only deletes images, not any other path(s).
    """
    if ask and not api.prompt.ask_question(
        title="delete", body=f"delete {quotedjoin(paths)}?"
    ):
        return
    _last_deleted.clear()
    images = [path for path in paths if files.is_image(path)]
    if not images:
        raise api.commands.CommandError("No images to delete")
    failed_images = []
    for filename in images:
        try:
            trash_filename = trash_manager.delete(filename)
            _last_deleted.append(os.path.basename(trash_filename))
        except OSError:
            failed_images.append(filename)

    n_fail = len(failed_images)
    n_success = len(images) - n_fail
    fail_msg = f"Failed to delete {', '.join(failed_images)}" if n_fail > 0 else ""
    succ_msg = f"Deleted {n_success} images" if n_success > 0 else ""

    if fail_msg:
        log.warning(f"{succ_msg + ' but ' if succ_msg else ''}{fail_msg}")
    elif succ_msg:
        log.info(succ_msg)
コード例 #11
0
def _write(pixmap, path, original_path):
    """Write pixmap to disk.

    See write_pixmap for the args description.
    """
    # Get pixmap type
    _, ext = os.path.splitext(path)
    # First create temporary file and then move it to avoid race conditions
    handle, filename = tempfile.mkstemp(suffix=ext)
    os.close(handle)
    pixmap.save(filename)
    # Copy exif info from original file to new file
    try:
        imutils.exif.ExifHandler(original_path).copy_exif(filename)
    except imutils.exif.UnsupportedExifOperation:
        pass
    shutil.move(filename, path)
    # Check if valid image was created
    if not os.path.isfile(path):
        raise WriteError("File not written, unknown exception")
    if not files.is_image(path):
        os.remove(path)
        raise WriteError("No valid image written. Is the extention valid?")
コード例 #12
0
def test_is_image_on_fifo_file(qtbot, tmp_path):
    path = tmp_path / "my_file"
    os.mkfifo(path)
    assert files.is_image(str(path)) is False
コード例 #13
0
def test_is_image_on_error(tmp_path):
    path = tmp_path / "my_file"
    path.touch(mode=0o000)
    assert files.is_image(str(path)) is False
コード例 #14
0
def test_is_image_on_error(tmpdir):
    path = tmpdir.join("my_file")
    path.write("")
    path.chmod(0o00)
    assert files.is_image(path) is False