Commit d0cb7e45 authored by Roman Alifanov's avatar Roman Alifanov

command_runner.py: refactoring

parent 86bcf940
......@@ -8,25 +8,17 @@ import selectors
from gi.repository import GLib
class CommandRunner:
def __init__(self, on_done=None):
def __init__(self):
self.dialog = None
self.textbuffer = None
self.yes_no_chars = 'yYдДnNнН' # Define the set of "yes" and "no" characters
self.on_done = on_done # Callback function to be called after completion
def run_command(self, command, dialog):
# Define the set of "yes" and "no" characters
yes_no_chars = 'yYдДnNнН'
self.dialog = dialog
self.textbuffer = dialog.logdialog_textview.get_buffer()
def append_log(text):
def append_log(self, text):
GLib.idle_add(self.textbuffer.insert_at_cursor, text)
GLib.idle_add(dialog.logdialog_textview.scroll_to_mark,
GLib.idle_add(self.dialog.logdialog_textview.scroll_to_mark,
self.textbuffer.get_insert(), 0, False, 0.0, 1.0)
def remove_ansi_escape_sequences(text):
def remove_ansi_escape_sequences(self, text):
result = []
in_escape = False
......@@ -38,21 +30,11 @@ class CommandRunner:
elif not in_escape:
result.append(char)
return ''.join(result)
def read_output(fd):
while True:
try:
output = os.read(fd, 1024).decode('utf-8', errors='replace')
if output:
cleaned_output = remove_ansi_escape_sequences(output)
append_log(cleaned_output)
self.dialog.question_revealer.set_reveal_child(False)
def handle_question(self, cleaned_output, fd):
# Check for the pattern in the output (letters in any order)
pattern = rf'\[([{yes_no_chars}])/([{yes_no_chars}])\]'
pattern = rf'\[([{self.yes_no_chars}])/([{self.yes_no_chars}])\]'
match = re.search(pattern, cleaned_output)
if match:
......@@ -80,13 +62,26 @@ class CommandRunner:
self.dialog.question_button_1.add_css_class("suggested-action")
self.dialog.question_revealer.set_reveal_child(True)
def read_output(self, fd):
while True:
try:
output = os.read(fd, 1024).decode('utf-8', errors='replace')
if output:
cleaned_output = self.remove_ansi_escape_sequences(output)
self.append_log(cleaned_output)
self.dialog.question_revealer.set_reveal_child(False)
self.handle_question(cleaned_output, fd)
else:
break
except OSError as e:
except OSError:
# Break the loop on I/O errors, assuming the process has terminated
break
def process_runner():
def process_runner(self, command):
process = None
sel = None
master_fd, slave_fd = pty.openpty()
try:
env = os.environ.copy()
......@@ -105,7 +100,7 @@ class CommandRunner:
events = sel.select()
for key, _ in events:
if key.fileobj == master_fd:
read_output(master_fd)
self.read_output(master_fd)
# Check if process has finished
if process.poll() is not None:
......@@ -116,8 +111,13 @@ class CommandRunner:
os.close(master_fd)
process.wait()
GLib.idle_add(dialog.force_close)
GLib.idle_add(self.dialog.force_close)
if self.on_done:
GLib.idle_add(self.on_done) # Call the callback function after completion
threading.Thread(target=process_runner, daemon=True).start()
\ No newline at end of file
def run_command(self, command, on_done, dialog):
self.dialog = dialog
self.on_done = on_done
self.textbuffer = dialog.logdialog_textview.get_buffer()
threading.Thread(target=self.process_runner, args=(command,), daemon=True).start()
......@@ -19,5 +19,5 @@ class LogDialog(Adw.Dialog):
def run(self, command, on_done):
self.present(self.win)
# Создание и передача функции обратного вызова для обновления UI
runner = CommandRunner(on_done=on_done)
runner.run_command(command, self)
runner = CommandRunner()
runner.run_command(command, on_done, dialog=self)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment