Пример #1
0
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 _run_command(count: str, cmdname: str, args: List[str],
                 mode: api.modes.Mode) -> None:
    """Run a given command.

    Args:
        count: Count to use for the command.
        cmdname: Name of the command passed.
        args: Arguments passed.
        mode: Mode to run the command in.
    """
    try:
        cmd = api.commands.get(cmdname, mode)
        if cmd.store:
            _last_command[mode] = LastCommand(count, cmdname, args)
        cmd(args, count=count)
        api.status.update("ran command")
    except api.commands.CommandNotFound as e:
        log.error(str(e))
        raise CommandPartFailed from e
    except (
            api.commands.ArgumentError,
            api.commands.CommandError,
            api.modes.InvalidMode,
    ) as e:
        log.error("%s: %s", cmdname, e)
        raise CommandPartFailed from e
    except api.commands.CommandWarning as w:
        log.warning("%s: %s", cmdname, str(w))
        raise CommandPartFailed from w
    except api.commands.CommandInfo as i:
        log.info("%s: %s", cmdname, i)
        raise CommandPartFailed from i
Пример #3
0
    def handle_interrupt(self, signum: int, _frame: Optional[types.FrameType]) -> None:
        """Initial handler for interrupt signals to exit gracefully.

        Args:
            signum: Signal number of the interrupt signal retrieved.
        """
        _logger.debug("Interrupt handler called with signal %d", signum)
        _assign_interrupt_handler(self.handle_interrupt_forcefully)
        log.info("SIGINT/SIGTERM received, exiting gracefully...")
        log.info("To kill the process repeat the signal")
        QTimer.singleShot(
            0, functools.partial(self._app.exit, customtypes.Exit.signal + signum)
        )
Пример #4
0
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)
Пример #5
0
def write_pixmap(pixmap, path, original_path):
    """Write pixmap to file.

    This requires both the path to write to and the original path as Exif data
    may be copied from the original path to the new copy. The procedure is to
    write the path to a temporary file first, transplant the Exif data to the
    temporary file if possible and finally rename the temporary file to the
    final path. The renaming is done as it is an atomic operation and we may be
    overriding the existing file.

    Args:
        pixmap: The QPixmap to write.
        path: Path to write the pixmap to.
        original_path: Original path of the opened pixmap to retrieve exif information.
    """
    try:
        _can_write(pixmap, path)
        _logger.debug("Image is writable")
        _write(pixmap, path, original_path)
        log.info("Saved %s", path)
    except WriteError as e:
        log.error(str(e))
Пример #6
0
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)
Пример #7
0
def help_command(topic: str) -> None:
    """Show help on a command or setting.

    **syntax:** ``:help topic``

    positional arguments:
        * ``topic``: Either a valid :command or a valid setting name.

    .. hint:: For commands ``help :command`` is the same as ``command -h``.
    """
    topic = topic.lower().lstrip(":")
    if topic == "vimiv":
        log.info(
            "%s: %s\n\n"
            "Website: %s\n\n"
            "For an overview of keybindings, run :keybindings.\n"
            "To retrieve help on a command or setting run :help topic.",
            vimiv.__name__,
            vimiv.__description__,
            vimiv.__url__,
        )
        return
    with suppress(api.commands.CommandNotFound):
        command = api.commands.get(topic, mode=api.modes.current())
        # This raises an exception and leaves this command
        command(["-h"], "")
    with suppress(KeyError):
        setting = api.settings.get(topic)
        log.info(
            "%s: %s\n\nType: %s\nDefault: %s\nSuggestions: %s",
            setting.name,
            setting.desc,
            setting,
            setting.default,
            ", ".join(setting.suggestions()),
        )
        return
    raise api.commands.CommandError(f"Unknown topic '{topic}'")
Пример #8
0
def _format_help(*, title: str, description: str, text: str = None) -> None:
    """Helper function to unify formatting of help texts."""
    header = add_html(title, "h3")
    text = f"{text}<br>" if text is not None else ""
    log.info("%s\n%s<br>%s", header, description, text)