Ejemplo n.º 1
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
Ejemplo n.º 2
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
Ejemplo n.º 3
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("")
Ejemplo n.º 4
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)