tweak to log

This commit is contained in:
Will McGugan
2022-04-12 16:18:10 +01:00
parent 72b39f0ed1
commit 352c8b789d
6 changed files with 86 additions and 35 deletions

View File

@@ -58,7 +58,7 @@ App > Screen {
#header { #header {
color: $text-primary-darken-1; color: $text-primary-darken-1;
background: $primary-darken-1; background: $primary-darken-1;
height: 3; height: 3
} }
@@ -74,9 +74,9 @@ App > Screen {
Tweet { Tweet {
height: 22; height: 22;
max-width: 80; max-width: 80;
margin: 1 3; margin: 1 3;
background: $panel; background: $panel;
color: $text-panel color: $text-panel;
layout: vertical; layout: vertical;
/* border: outer $primary; */ /* border: outer $primary; */
padding: 1; padding: 1;

View File

@@ -4,6 +4,7 @@ import asyncio
import inspect import inspect
import os import os
import platform import platform
from time import perf_counter
import warnings import warnings
from asyncio import AbstractEventLoop from asyncio import AbstractEventLoop
from pathlib import Path from pathlib import Path
@@ -29,7 +30,7 @@ from ._callback import invoke
from ._context import active_app from ._context import active_app
from ._event_broker import extract_handler_actions, NoHandler from ._event_broker import extract_handler_actions, NoHandler
from .binding import Bindings, NoBinding from .binding import Bindings, NoBinding
from .css.stylesheet import Stylesheet, StylesheetParseError, StylesheetError from .css.stylesheet import Stylesheet
from .devtools.client import DevtoolsClient, DevtoolsConnectionError from .devtools.client import DevtoolsClient, DevtoolsConnectionError
from .design import ColorSystem from .design import ColorSystem
from .dom import DOMNode from .dom import DOMNode
@@ -102,6 +103,7 @@ class App(DOMNode):
""" """
self.console = Console(markup=False, highlight=False) self.console = Console(markup=False, highlight=False)
self.error_console = Console(markup=False, stderr=True) self.error_console = Console(markup=False, stderr=True)
self._screen = screen self._screen = screen
self.driver_class = driver_class or self.get_driver_class() self.driver_class = driver_class or self.get_driver_class()
self._title = title self._title = title
@@ -121,7 +123,16 @@ class App(DOMNode):
self.bindings = Bindings() self.bindings = Bindings()
self._title = title self._title = title
self.log_file = open(log, "wt") if log else None self._log_console: Console | None = None
if log:
self.log_file = open(log, "wt")
self._log_console = Console(
file=self.log_file, markup=False, emoji=False, highlight=False
)
else:
self._log_console = None
self._log_file = None
self.log_verbosity = log_verbosity self.log_verbosity = log_verbosity
self.bindings.bind("ctrl+c", "quit", show=False, allow_forward=False) self.bindings.bind("ctrl+c", "quit", show=False, allow_forward=False)
@@ -219,30 +230,36 @@ class App(DOMNode):
_textual_calling_frame (inspect.FrameInfo | None): The frame info to include in _textual_calling_frame (inspect.FrameInfo | None): The frame info to include in
the log message sent to the devtools server. the log message sent to the devtools server.
""" """
output = "" if verbosity > self.log_verbosity:
return
try: try:
output = f" ".join(str(arg) for arg in objects) if len(objects) == 1:
if kwargs: if self._log_console is not None:
key_values = " ".join(f"{key}={value}" for key, value in kwargs.items()) self._log_console.print(objects[0])
output = " ".join((output, key_values)) if self.devtools.is_connected:
if not _textual_calling_frame:
if not _textual_calling_frame: _textual_calling_frame = inspect.stack()[1]
_textual_calling_frame = inspect.stack()[1] calling_path = _textual_calling_frame.filename
calling_lineno = _textual_calling_frame.lineno
calling_path = _textual_calling_frame.filename
calling_lineno = _textual_calling_frame.lineno
if self.devtools.is_connected and verbosity <= self.log_verbosity:
if len(objects) > 1 or len(kwargs) >= 1 and output:
self.devtools.log(output, path=calling_path, lineno=calling_lineno)
else:
self.devtools.log( self.devtools.log(
*objects, path=calling_path, lineno=calling_lineno objects[0], path=calling_path, lineno=calling_lineno
) )
else:
if self.log_file and verbosity <= self.log_verbosity: output = f" ".join(str(arg) for arg in objects)
self.log_file.write(output + "\n") if kwargs:
self.log_file.flush() key_values = " ".join(
f"{key}={value}" for key, value in kwargs.items()
)
output = " ".join((output, key_values))
if self._log_console is not None:
self._log_console.print(output, soft_wrap=True)
if self.devtools.is_connected:
if not _textual_calling_frame:
_textual_calling_frame = inspect.stack()[1]
calling_path = _textual_calling_frame.filename
calling_lineno = _textual_calling_frame.lineno
self.devtools.log(output, path=calling_path, lineno=calling_lineno)
except Exception: except Exception:
pass pass
@@ -310,11 +327,13 @@ class App(DOMNode):
if self.css_file is not None: if self.css_file is not None:
stylesheet = Stylesheet(variables=self.get_css_variables()) stylesheet = Stylesheet(variables=self.get_css_variables())
try: try:
self.log("loading", self.css_file) time = perf_counter()
stylesheet.read(self.css_file) stylesheet.read(self.css_file)
except StylesheetError as error: elapsed = (perf_counter() - time) * 1000
self.log(error) self.log(f"loaded {self.css_file} in {elapsed:.0f}ms")
except Exception as error:
self.console.bell() self.console.bell()
self.log(error)
else: else:
self.reset_styles() self.reset_styles()
self.stylesheet = stylesheet self.stylesheet = stylesheet

View File

@@ -275,8 +275,8 @@ class StylesBuilder:
space: list[int] = [] space: list[int] = []
append = space.append append = space.append
for token in tokens: for token in tokens:
token_name, value, _, _, location, _ = token token_name, value, _, _, _, _ = token
if token_name in ("number", "scalar"): if token_name == "number":
try: try:
append(int(value)) append(int(value))
except ValueError: except ValueError:
@@ -289,12 +289,44 @@ class StylesBuilder:
) )
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space))) self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space)))
def _process_space_partial(self, name: str, tokens: list[Token]) -> None:
if len(tokens) != 1:
self.error(name, tokens[0], "expected a single token here")
_EDGE_SPACING_MAP = {"top": 0, "right": 1, "bottom": 2, "left": 3}
token = tokens[0]
token_name, value, _, _, _, _ = token
if token_name == "number":
space = int(value)
else:
self.error(name, token, f"expected a number here; found {value!r}")
style_name, _, edge = name.replace("-", "_").partition("_")
current_spacing = cast(
tuple[int, int, int, int], self.styles._rules.get(style_name, (0, 0, 0, 0))
)
spacing_list = list(current_spacing)
spacing_list[_EDGE_SPACING_MAP[edge]] = space
self.styles._rules[style_name] = Spacing(*spacing_list)
def process_padding(self, name: str, tokens: list[Token]) -> None: def process_padding(self, name: str, tokens: list[Token]) -> None:
self._process_space(name, tokens) self._process_space(name, tokens)
def process_margin(self, name: str, tokens: list[Token]) -> None: def process_margin(self, name: str, tokens: list[Token]) -> None:
self._process_space(name, tokens) self._process_space(name, tokens)
process_margin_top = _process_space_partial
process_margin_right = _process_space_partial
process_margin_bottom = _process_space_partial
process_margin_left = _process_space_partial
process_padding_top = _process_space_partial
process_padding_right = _process_space_partial
process_padding_bottom = _process_space_partial
process_padding_left = _process_space_partial
def _parse_border(self, name: str, tokens: list[Token]) -> tuple[str, Color]: def _parse_border(self, name: str, tokens: list[Token]) -> tuple[str, Color]:
border_type = "solid" border_type = "solid"
border_color = Color(0, 255, 0) border_color = Color(0, 255, 0)

View File

@@ -28,7 +28,7 @@ from ..dom import DOMNode
from .. import log from .. import log
class StylesheetParseError(Exception): class StylesheetParseError(StylesheetError):
def __init__(self, errors: StylesheetErrors) -> None: def __init__(self, errors: StylesheetErrors) -> None:
self.errors = errors self.errors = errors

View File

@@ -202,7 +202,7 @@ class Key(InputEvent):
@rich.repr.auto @rich.repr.auto
class MouseEvent(InputEvent, bubble=True): class MouseEvent(InputEvent, bubble=True, verbosity=2):
"""Sent in response to a mouse event""" """Sent in response to a mouse event"""
__slots__ = [ __slots__ = [
@@ -344,7 +344,7 @@ class MouseScrollDown(InputEvent, verbosity=3, bubble=True):
self.y = y self.y = y
class MouseScrollUp(MouseScrollDown, bubble=True): class MouseScrollUp(MouseScrollDown, verbosity=3, bubble=True):
pass pass

View File

@@ -91,7 +91,7 @@ class Screen(Widget):
def on_idle(self, event: events.Idle) -> None: def on_idle(self, event: events.Idle) -> None:
# Check for any widgets marked as 'dirty' (needs a repaint) # Check for any widgets marked as 'dirty' (needs a repaint)
if self._dirty_widgets: if self._dirty_widgets:
self.log(dirty=len(self._dirty_widgets)) # self.log(dirty=len(self._dirty_widgets))
for widget in self._dirty_widgets: for widget in self._dirty_widgets:
# Repaint widgets # Repaint widgets
# TODO: Combine these in to a single update. # TODO: Combine these in to a single update.