More pep8 fixes. A tiny bit of refactoring.

This commit is contained in:
Storm Dragon
2025-07-07 00:42:23 -04:00
parent d28c18faed
commit 3390c25dfe
343 changed files with 11092 additions and 7582 deletions

View File

@ -2,21 +2,23 @@
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
# By Chrys, Storm Dragon, and contributors.
import os
import struct
import sys
import pty
import tty
import termios
import shlex
import signal
import pyte
import time
import fcntl
import getpass
import os
import pty
import shlex
import signal
import struct
import sys
import termios
import time
import tty
from select import select
import pyte
from fenrirscreenreader.core import debug
from fenrirscreenreader.core.eventData import FenrirEventType
from fenrirscreenreader.core.screenDriver import ScreenDriver as screenDriver
@ -31,11 +33,12 @@ class FenrirScreen(pyte.Screen):
class Terminal:
def __init__(self, columns, lines, p_in):
self.text = ''
self.text = ""
self.attributes = None
self.screen = FenrirScreen(columns, lines)
self.screen.write_process_input = \
lambda data: p_in.write(data.encode())
self.screen.write_process_input = lambda data: p_in.write(
data.encode()
)
self.stream = pyte.ByteStream()
self.stream.attach(self.screen)
@ -49,8 +52,13 @@ class Terminal:
lines = self.screen.dirty
else:
lines = range(self.screen.lines)
self.attributes = [[list(attribute[1:]) + [False, 'default', 'default']
for attribute in line.values()] for line in buffer.values()]
self.attributes = [
[
list(attribute[1:]) + [False, "default", "default"]
for attribute in line.values()
]
for line in buffer.values()
]
for y in lines:
try:
t = self.attributes[y]
@ -58,23 +66,30 @@ class Terminal:
# Terminal class doesn't have access to env, use fallback
# logging
print(
f'ptyDriver Terminal update_attributes: Error accessing attributes: {e}')
f"ptyDriver Terminal update_attributes: Error accessing attributes: {e}"
)
self.attributes.append([])
self.attributes[y] = [list(
attribute[1:]) + [False, 'default', 'default'] for attribute in (buffer[y].values())]
self.attributes[y] = [
list(attribute[1:]) + [False, "default", "default"]
for attribute in (buffer[y].values())
]
if len(self.attributes[y]) < self.screen.columns:
diff = self.screen.columns - len(self.attributes[y])
self.attributes[y] += [['default',
'default',
False,
False,
False,
False,
False,
False,
'default',
'default']] * diff
self.attributes[y] += [
[
"default",
"default",
False,
False,
False,
False,
False,
False,
"default",
"default",
]
] * diff
def resize(self, lines, columns):
self.screen.resize(lines, columns)
@ -89,23 +104,24 @@ class Terminal:
if y_pos == -1:
y_pos = self.screen.cursor.y
self.screen.cursor.x = min(
self.screen.cursor.x,
self.screen.columns - 1)
self.screen.cursor.x, self.screen.columns - 1
)
self.screen.cursor.y = min(self.screen.cursor.y, self.screen.lines - 1)
def get_screen_content(self):
cursor = self.screen.cursor
self.text = '\n'.join(self.screen.display)
self.text = "\n".join(self.screen.display)
self.update_attributes(self.attributes is None)
self.screen.dirty.clear()
return {"cursor": (cursor.x, cursor.y),
'lines': self.screen.lines,
'columns': self.screen.columns,
"text": self.text,
'attributes': self.attributes.copy(),
'screen': 'pty',
'screenUpdateTime': time.time(),
}.copy()
return {
"cursor": (cursor.x, cursor.y),
"lines": self.screen.lines,
"columns": self.screen.columns,
"text": self.text,
"attributes": self.attributes.copy(),
"screen": "pty",
"screenUpdateTime": time.time(),
}.copy()
class driver(screenDriver):
@ -119,31 +135,34 @@ class driver(screenDriver):
def initialize(self, environment):
self.env = environment
self.command = self.env['runtime']['SettingsManager'].get_setting(
'general', 'shell')
self.shortcutType = self.env['runtime']['InputManager'].get_shortcut_type(
self.command = self.env["runtime"]["SettingsManager"].get_setting(
"general", "shell"
)
self.shortcutType = self.env["runtime"][
"InputManager"
].get_shortcut_type()
self.env["runtime"]["ProcessManager"].add_custom_event_thread(
self.terminal_emulation
)
self.env['runtime']['ProcessManager'].add_custom_event_thread(
self.terminal_emulation)
def get_curr_screen(self):
self.env['screen']['oldTTY'] = 'pty'
self.env['screen']['newTTY'] = 'pty'
self.env["screen"]["oldTTY"] = "pty"
self.env["screen"]["newTTY"] = "pty"
def inject_text_to_screen(self, msg_bytes, screen=None):
if not screen:
screen = self.p_out.fileno()
if isinstance(msg_bytes, str):
msg_bytes = bytes(msg_bytes, 'UTF-8')
msg_bytes = bytes(msg_bytes, "UTF-8")
os.write(screen, msg_bytes)
def get_session_information(self):
self.env['screen']['autoIgnoreScreens'] = []
self.env['general']['prev_user'] = getpass.getuser()
self.env['general']['curr_user'] = getpass.getuser()
self.env["screen"]["autoIgnoreScreens"] = []
self.env["general"]["prev_user"] = getpass.getuser()
self.env["general"]["curr_user"] = getpass.getuser()
def read_all(self, fd, timeout=0.3, interruptFd=None, len=65536):
msg_bytes = b''
msg_bytes = b""
fd_list = []
fd_list += [fd]
if interruptFd:
@ -155,7 +174,7 @@ class driver(screenDriver):
if fd not in r:
break
data = os.read(fd, len)
if data == b'':
if data == b"":
raise EOFError
msg_bytes += data
# exit on interrupt available
@ -174,44 +193,47 @@ class driver(screenDriver):
env = os.environ.copy()
# values are VT100,xterm-256color,linux
try:
if env["TERM"] == '':
env["TERM"] = 'linux'
if env["TERM"] == "":
env["TERM"] = "linux"
except Exception as e:
# Child process doesn't have access to env, use fallback
# logging
print(
f'ptyDriver spawnTerminal: Error checking TERM environment: {e}')
env["TERM"] = 'linux'
f"ptyDriver spawnTerminal: Error checking TERM environment: {e}"
)
env["TERM"] = "linux"
os.execvpe(argv[0], argv, env)
# File-like object for I/O with the child process aka command.
p_out = os.fdopen(master_fd, "w+b", 0)
return Terminal(columns, lines, p_out), p_pid, p_out
def resize_terminal(self, fd):
s = struct.pack('HHHH', 0, 0, 0, 0)
s = struct.pack("HHHH", 0, 0, 0, 0)
s = fcntl.ioctl(0, termios.TIOCGWINSZ, s)
fcntl.ioctl(fd, termios.TIOCSWINSZ, s)
lines, columns, _, _ = struct.unpack('hhhh', s)
lines, columns, _, _ = struct.unpack("hhhh", s)
return lines, columns
def get_terminal_size(self, fd):
s = struct.pack('HHHH', 0, 0, 0, 0)
s = struct.pack("HHHH", 0, 0, 0, 0)
lines, columns, _, _ = struct.unpack(
'HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s))
"HHHH", fcntl.ioctl(fd, termios.TIOCGWINSZ, s)
)
return lines, columns
def handle_sigwinch(self, *args):
os.write(self.signalPipe[1], b'w')
os.write(self.signalPipe[1], b"w")
def terminal_emulation(self, active, event_queue):
try:
old_attr = termios.tcgetattr(sys.stdin)
tty.setraw(0)
lines, columns = self.get_terminal_size(0)
if self.command == '':
if self.command == "":
self.command = screen_utils.get_shell()
self.terminal, self.p_pid, self.p_out = self.open_terminal(
columns, lines, self.command)
columns, lines, self.command
)
lines, columns = self.resize_terminal(self.p_out)
self.terminal.resize(lines, columns)
fd_list = [sys.stdin, self.p_out, self.signalPipe[0]]
@ -231,29 +253,50 @@ class driver(screenDriver):
msg_bytes = self.read_all(sys.stdin.fileno(), len=4096)
except (EOFError, OSError):
event_queue.put(
{"Type": FenrirEventType.stop_main_loop, "data": None})
{
"Type": FenrirEventType.stop_main_loop,
"data": None,
}
)
break
if self.shortcutType == 'KEY':
if self.shortcutType == "KEY":
try:
self.inject_text_to_screen(msg_bytes)
except Exception as e:
self.env['runtime']['DebugManager'].write_debug_out(
'ptyDriver getInputData: Error injecting text to screen: ' + str(e),
debug.DebugLevel.ERROR)
self.env["runtime"][
"DebugManager"
].write_debug_out(
"ptyDriver getInputData: Error injecting text to screen: "
+ str(e),
debug.DebugLevel.ERROR,
)
event_queue.put(
{"Type": FenrirEventType.stop_main_loop, "data": None})
{
"Type": FenrirEventType.stop_main_loop,
"data": None,
}
)
break
else:
event_queue.put({"Type": FenrirEventType.byte_input,
"data": msg_bytes})
event_queue.put(
{
"Type": FenrirEventType.byte_input,
"data": msg_bytes,
}
)
# output
if self.p_out in r:
try:
msg_bytes = self.read_all(
self.p_out.fileno(), interruptFd=sys.stdin.fileno())
self.p_out.fileno(), interruptFd=sys.stdin.fileno()
)
except (EOFError, OSError):
event_queue.put(
{"Type": FenrirEventType.stop_main_loop, "data": None})
{
"Type": FenrirEventType.stop_main_loop,
"data": None,
}
)
break
# feed and send event bevore write, the pyte already has the right state
# so fenrir already can progress bevore os.write what
@ -263,19 +306,25 @@ class driver(screenDriver):
{
"Type": FenrirEventType.screen_update,
"data": screen_utils.create_screen_event_data(
self.terminal.get_screen_content())})
self.terminal.get_screen_content()
),
}
)
self.inject_text_to_screen(
msg_bytes, screen=sys.stdout.fileno())
msg_bytes, screen=sys.stdout.fileno()
)
except Exception as e: # Process died?
print(e)
event_queue.put(
{"Type": FenrirEventType.stop_main_loop, "data": None})
{"Type": FenrirEventType.stop_main_loop, "data": None}
)
finally:
os.kill(self.p_pid, signal.SIGTERM)
self.p_out.close()
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
event_queue.put(
{"Type": FenrirEventType.stop_main_loop, "data": None})
{"Type": FenrirEventType.stop_main_loop, "data": None}
)
sys.exit(0)
def get_curr_application(self):