Beispiel #1
0
    def _try_generate_thumbnail(cls, ffmpeg, movie_path):
        logger = logging.getLogger(__name__)

        try:
            thumb_path = create_thumbnail_path(movie_path)
            commandline = settings().get(
                ["webcam", "ffmpegThumbnailCommandline"])
            thumb_command_str = cls._create_ffmpeg_command_string(
                commandline=commandline,
                ffmpeg=ffmpeg,
                input=movie_path,
                output=thumb_path,
                fps=None,
                videocodec=None,
                threads=None,
                bitrate=None,
            )
            c = CommandlineCaller()
            returncode, stdout_text, stderr_text = c.call(thumb_command_str,
                                                          delimiter=b"\r",
                                                          buffer_size=512)
            if returncode != 0:
                logger.warning("Failed to generate optional thumbnail %r: %s" %
                               (returncode, stderr_text))
            return True
        except Exception as ex:
            logger.warning(
                "Failed to generate thumbnail from {} to {} ({})".format(
                    movie_path, thumb_path, ex))
            return False
Beispiel #2
0
def run_system_command(command, password=None):
    logger = logging.getLogger(
        "octoprint.plugins.ws281x_led_status.commandline")
    caller = CommandlineCaller()
    try:
        if password:
            returncode, stdout, stderr = caller.call(command, input=password)
        else:
            returncode, stdout, stderr = caller.call(command)

    except Exception as e:
        logger.error("Error running command `{}`".format("".join(command)))
        logger.exception(e)
        return None, "exception"

    if returncode != 0:
        logger.error("Command for `{}` failed with return code {}".format(
            "".join(command), returncode))
        logger.error("STDOUT: {}".format(stdout))
        logger.error("STDOUT: {}".format(stderr))
        error = "command"
    else:
        # Convert output to joined string instead of list
        stdout = "\n".join(stdout)
        stderr = "\n".join(stderr)

        if stderr and "Sorry" in stderr or "no password" in stdout:
            error = "password"
        else:
            error = None

    return stdout, error
Beispiel #3
0
        def execute():
            # we run this with shell=True since we have to trust whatever
            # our admin configured as command and since we want to allow
            # shell-alike handling here...
            return_code, stdout_lines, stderr_lines = CommandlineCaller().call(
                command_spec["command"], shell=True)

            if not do_ignore and return_code != 0:
                stdout = "\n".join(stdout_lines)
                stderr = "\n".join(stderr_lines)
                error = f"Command for {source}:{command} failed with return code {return_code}:\n\nSTDOUT:\n{stdout}\n\nSTDERR:\n{stderr}"
                logger.warning(prefix_multilines(error, prefix="! "))
                if not do_async:
                    raise CommandFailed(error)
Beispiel #4
0
	def __init__(self, *args, **kwargs):
		click.MultiCommand.__init__(self, *args, **kwargs)

		from octoprint.util.commandline import CommandlineCaller
		from functools import partial

		def log_util(f):
			def log(*lines):
					for line in lines:
						f(line)
			return log

		self.command_caller = CommandlineCaller()
		self.command_caller.on_log_call = log_util(lambda x: click.echo(">> {}".format(x)))
		self.command_caller.on_log_stdout = log_util(click.echo)
		self.command_caller.on_log_stderr = log_util(partial(click.echo, err=True))
    def restart_octoprint(self):
        command = self._octoprint_settings.get(["server", "commands", "serverRestartCommand"])
        if not command:
            self._logger.warning("No command configured, can't restart")
            return

        caller = CommandlineCaller()
        try:
            code, stdout, stderr = caller.call(command, **{"shell": True}) # Use shell=True, as we have to trust user input
        except Exception as e:
            self._logger.error("Error calling command to restart server {}".format(command))
            self._logger.exception(e)
            return

        if code != 0:
            self._logger.error("Non zero return code running '{}' to restart server: {}".format(command, code))
            self._logger.exception("STDOUT: {}".format(stdout))
            self._logger.exception("STDERR: {}".format(stderr))
Beispiel #6
0
def _get_caller(log_cb=None):
    def _log_call(*lines):
        _log(lines, prefix=" ", stream="call")

    def _log_stdout(*lines):
        _log(lines, prefix=">", stream="stdout")

    def _log_stderr(*lines):
        _log(lines, prefix="!", stream="stderr")

    def _log(lines, prefix=None, stream=None):
        if log_cb is None:
            return
        log_cb(lines, prefix=prefix, stream=stream)

    caller = CommandlineCaller()
    if log_cb is not None:
        caller.on_log_call = _log_call
        caller.on_log_stdout = _log_stdout
        caller.on_log_stderr = _log_stderr
    return caller
Beispiel #7
0
    def _do_copy_log(self):

        # Get the name of the tarball we're going to copy the log
        # files to.
        tarball_filename = self.build_tarball_filename()
        self._log("tarball = <%s>" % tarball_filename)

        # Get the location where we're going to save the tarball.
        logpath = self.find_logpath()
        self._log("logpath = <%s>" % logpath)

        # Build the full path to the tarball
        tarball_path = os.path.join(logpath, tarball_filename)
        self._log("tarball_path = <%s>" % tarball_path)

        # Get the names of the log files
        logfiles = self.get_log_file_names()
        self._log("logfiles = <%s>" % logfiles)

        # Now build the command.
        command = "tar cvf %s %s" % (tarball_path, logfiles)
        self._log("command = <%s>" % command)

        # Construct a commandline caller to run the tar command.
        caller = CommandlineCaller()
        caller.on_log_call = self.display_call_stdout
        caller.on_log_stdout = self.display_call_stdout
        caller.on_log_stderr = self.display_stderr

        # Execute the command.
        self.display("")
        caller.call(command)

        # Finish off with a message stating that the tarball has been
        # created.
        done_message = "Logs copied to file \"%s\"" % tarball_path
        self._log(done_message)
        self.display("\n" + done_message)
        self.display("")
Beispiel #8
0
    def _render(self):
        """Rendering runnable."""

        ffmpeg = settings().get(["webcam", "ffmpeg"])
        commandline = settings().get(["webcam", "ffmpegCommandline"])
        bitrate = settings().get(["webcam", "bitrate"])
        if ffmpeg is None or bitrate is None:
            self._logger.warning(
                "Cannot create movie, path to ffmpeg or desired bitrate is unset"
            )
            return

        if self._videocodec == "mpeg2video":
            extension = "mpg"
        else:
            extension = "mp4"

        input = os.path.join(
            self._capture_dir,
            self._capture_format.format(
                prefix=self._prefix,
                postfix=self._postfix if self._postfix is not None else "",
            ),
        )

        output_name = self._output_format.format(
            prefix=self._prefix,
            postfix=self._postfix if self._postfix is not None else "",
            extension=extension,
        )
        temporary = os.path.join(self._output_dir, ".{}".format(output_name))
        output = os.path.join(self._output_dir, output_name)

        for i in range(4):
            if os.path.exists(input % i):
                break
        else:
            self._logger.warning("Cannot create a movie, no frames captured")
            self._notify_callback(
                "fail", output, returncode=0, stdout="", stderr="", reason="no_frames"
            )
            return

        hflip = settings().getBoolean(["webcam", "flipH"])
        vflip = settings().getBoolean(["webcam", "flipV"])
        rotate = settings().getBoolean(["webcam", "rotate90"])

        watermark = None
        if settings().getBoolean(["webcam", "watermark"]):
            watermark = os.path.join(
                os.path.dirname(__file__), "static", "img", "watermark.png"
            )
            if sys.platform == "win32":
                # Because ffmpeg hiccups on windows' drive letters and backslashes we have to give the watermark
                # path a special treatment. Yeah, I couldn't believe it either...
                watermark = watermark.replace("\\", "/").replace(":", "\\\\:")

        # prepare ffmpeg command
        command_str = self._create_ffmpeg_command_string(
            commandline,
            ffmpeg,
            self._fps,
            bitrate,
            self._threads,
            input,
            temporary,
            self._videocodec,
            hflip=hflip,
            vflip=vflip,
            rotate=rotate,
            watermark=watermark,
        )
        self._logger.debug("Executing command: {}".format(command_str))

        with self.render_job_lock:
            try:
                self._notify_callback("start", output)

                self._logger.debug("Parsing ffmpeg output")

                c = CommandlineCaller()
                c.on_log_stderr = self._process_ffmpeg_output
                returncode, stdout_text, stderr_text = c.call(
                    command_str, delimiter=b"\r", buffer_size=512
                )

                self._logger.debug("Done with parsing")

                if returncode == 0:
                    shutil.move(temporary, output)
                    self._notify_callback("success", output)
                else:
                    self._logger.warning(
                        "Could not render movie, got return code %r: %s"
                        % (returncode, stderr_text)
                    )
                    self._notify_callback(
                        "fail",
                        output,
                        returncode=returncode,
                        stdout=stdout_text,
                        stderr=stderr_text,
                        reason="returncode",
                    )
            except Exception:
                self._logger.exception("Could not render movie due to unknown error")
                self._notify_callback("fail", output, reason="unknown")
            finally:
                try:
                    if os.path.exists(temporary):
                        os.remove(temporary)
                except Exception:
                    self._logger.warning(
                        "Could not delete temporary timelapse {}".format(temporary)
                    )
                self._notify_callback("always", output)
Beispiel #9
0
 def __init__(self):
     self._logger = logging.getLogger(__name__)
     self._caller = CommandlineCaller()
 def __init__(self, simply_print):
     self.simply_print = simply_print
     self._logger = logging.getLogger(
         "octoprint.plugins.SimplyPrint.comm.startup")
     self.startup_thread = None
     self.command_line = CommandlineCaller()