def _on_process_stdout(self, *args): s = self._process.stdout.read() self._process.stdout_remainder += s *lines, self._process.stdout_remainder = \ self._process.stdout_remainder.split('\n') for line in lines: try: request = json.loads(line) method = getattr(self._handler, request['method']) result = method(*request['args']) with contextlib.suppress(BrokenPipeError): print(json.dumps({'result': result}), flush=True, file=self._process.stdin) except Exception: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'failed request %r\n%s', line, traceback.format_exc()) self._process.kill() if not s: if self._process.stdout_remainder: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'incomplete request %r', self._process.stdout_remainder) # Unset self._process first for self._on_process_stderr process, self._process = self._process, None self._handler.on_finished(process.wait() == 0) return False return True
def _on_process_stdout(self, *args): s = self._process.stdout.read() self._process.stdout_remainder += s *lines, self._process.stdout_remainder = \ self._process.stdout_remainder.split('\n') failure = False for line in lines: try: request = json.loads(line) method = getattr(self._handler, request['method']) result = method(*request['args']) print(json.dumps({'result': result}), flush=True, file=self._process.stdin) except Exception: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'failed request %r\n%s', line, traceback.format_exc()) failure = True break if not s and self._process.stdout_remainder: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'incomplete request %r', self._process.stdout_remainder) failure = True if not s or failure: # Unset self._process first for self._on_process_stderr process, self._process = self._process, None returncode = self._finish_process_and_kill_pgrp(process) self._handler.on_finished(returncode == 0 and not failure) return False return True
def _on_process_stdout(self, fd, condition, process): # Don't use `process.stdout.read` because of O_NONBLOCK (see `start`) s = process.stdout.buffer.read() pipe_closed = not s process.stdout_remainder += s *lines, process.stdout_remainder = self._splitlines_re.split( process.stdout_remainder) if self._process is not process: return not pipe_closed failure = False line: typing.AnyStr for line in filter(None, lines): # Filter empty lines try: line = line.decode(process.stdout.encoding) request = json.loads(line) method = getattr(self._handler, request['method']) result = method(*request['args']) print(json.dumps({'result': result}), file=process.stdin, flush=True) except Exception: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'failed request %r\n%s', line, traceback.format_exc()) failure = True break if pipe_closed and process.stdout_remainder: g_log(None, GLib.LogLevelFlags.LEVEL_CRITICAL, 'incomplete request %r', process.stdout_remainder) failure = True if pipe_closed or failure: returncode = self._finish_process_and_kill_pgrp() self._handler.on_finished(returncode == 0 and not failure) return not pipe_closed
def _on_process_stderr(self, fd, condition, process): s = process.stderr.read() process.stderr_remainder += s or '\n' *lines, process.stderr_remainder = process.stderr_remainder.split('\n') for line in filter(None, lines): g_log('youtube-dl', GLib.LogLevelFlags.LEVEL_DEBUG, '%s', line) if self._process is process: self._handler.on_pulse() return bool(s)
def on_notification_action(self, action_name): if action_name in ('notification-success', 'notification-error'): self.present() elif (action_name == 'notification-open-download-dir' and self.model.state == 'success'): self.model.open_download_dir() else: g_log(None, GLib.LogLevelFlags.LEVEL_WARNING, 'Action %r not supported in state %r', action_name, self.model.state)
def open_download_dir(self): if len(self._download_finished_filenames) == 1: method = 'ShowItems' paths = [os.path.join(self.download_dir_abs, filename) for filename in self._download_finished_filenames] else: method = 'ShowFolders' paths = [self.download_dir_abs] parameters = GLib.Variant( '(ass)', ([Gio.File.new_for_path(p).get_uri() for p in paths], '')) try: self._filemanager_proxy.call_sync( method, parameters, Gio.DBusCallFlags.NONE, -1) except GLib.Error: g_log(None, GLib.LogLevelFlags.LEVEL_WARNING, '%s', traceback.format_exc()) subprocess.run(['xdg-open', self.download_dir_abs], check=True)
def _on_process_stderr(self, fd, condition, process): # Don't use `process.stderr.read` because of O_NONBLOCK (see `start`) s = process.stderr.buffer.read() pipe_closed = not s process.stderr_remainder += s if pipe_closed: process.stderr_remainder += b'\n' *lines, process.stderr_remainder = self._splitlines_re.split( process.stderr_remainder) for line in filter(None, lines): # Filter empty lines # Don't use `errors='strict'` because programs might write garbage # to stderr line = line.decode(process.stderr.encoding, errors='replace') g_log('youtube-dl', GLib.LogLevelFlags.LEVEL_DEBUG, '%s', line) if self._process is process: self._handler.on_pulse() return not pipe_closed