Example #1
0
def open(paths: Iterable[str]) -> None:  # pylint: disable=redefined-builtin
    """Deprecated open function for backwards compatibility."""
    # TODO remove in v0.7.0
    log.warning(
        "Calling 'api.open' directly is deprecated, use 'api.open_paths' instead"
    )
    open_paths(paths)
Example #2
0
 def _on_quit(self):
     if self.state() == QProcess.Running:
         log.warning(
             "Decoupling external command '%s' with pid %d",
             self.program(),
             self.pid(),
         )
Example #3
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
Example #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")
    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)
Example #5
0
 def _open_path(self, path: str, close: bool):
     """Open a given path possibly closing the library."""
     if not path:
         log.warning("Library: selecting empty path")
     elif os.path.isdir(path):
         self._open_directory(path)
     else:
         self._open_image(path, close)
Example #6
0
def _log_unknown_module(module_name: str) -> None:
    """Display log warning for unknown module.

    The lru_cache is used so each module is only logged once, not on every evaluation of
    the status text.

    Args:
        module_name: Module string that is unknown.
    """
    log.warning("Disabling unknown statusbar module '%s'", module_name)
Example #7
0
 def _process_pipe(self) -> None:
     """Open paths from stdout."""
     _logger.debug("Opening paths from '%s'...", self.program())
     stdout = qbytearray_to_str(self.readAllStandardOutput())
     try:
         api.open_paths(path for path in stdout.split("\n") if os.path.exists(path))
         _logger.debug("... opened paths from pipe")
         api.status.update("opened paths from pipe")
     except api.commands.CommandError:
         log.warning("%s: No paths from pipe", self.program())
Example #8
0
 def __call__(self, command: str, *args: str, pipe=False) -> None:
     """Run external command with arguments."""
     if self.state() == QProcess.Running:
         log.warning("Closing running process '%s'", self.program())
         self.close()
     self._pipe = pipe
     arglist: List[str] = flatten(
         glob.glob(arg) if contains_any(arg, "*?[]") else (arg,) for arg in args
     )
     _logger.debug("Running external command '%s' with '%r'", command, arglist)
     self.start(command, arglist)
Example #9
0
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)
def run_startup_commands(*commands: str) -> None:
    """Run commands given via --command at startup.

    Args:
        commands: All command strings given via individual --command arguments.
    """
    total = len(commands)
    for i, command in enumerate(commands, start=1):
        _logger.debug("Startup commands: running %d/%d '%s'", i, total, command)
        if "quit" in command:  # This does not work without a running app
            log.warning("Quitting forcefully as the app does not exist")
            app.Application.preexit(customtypes.Exit.success)
            sys.exit(customtypes.Exit.success)
        else:
            runners.run(command, mode=api.modes.current())
Example #11
0
 def __init__(self, filename=""):
     super().__init__(filename)
     try:
         self._metadata = piexif.load(filename)
     except FileNotFoundError:
         _logger.debug("File %s not found", filename)
         self._metadata = None
     except piexif.InvalidImageDataError:
         log.warning(
             "Piexif only supports the file types JPEG and TIFF.<br>\n"
             "Please install pyexiv2 for better file type support.<br>\n"
             "For more information see<br>\n"
             "https://karlch.github.io/vimiv-qt/documentation/exif.html",
             once=True,
         )
         self._metadata = None
Example #12
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)
def log_warning(message, qtbot):
    log.warning(message)