From 8bb6fc119b6b832ff82887df437f950b17ea16e4 Mon Sep 17 00:00:00 2001 From: Shohan Dutta Roy Date: Sat, 9 Nov 2024 00:53:36 +0530 Subject: [PATCH] chore: Remove uses of nicegui and clean up files --- openadapt/deprecated/app/cards.py | 110 ----- openadapt/deprecated/app/main.py | 100 ----- openadapt/deprecated/app/objects/console.py | 42 -- .../app/objects/local_file_picker.py | 132 ------ openadapt/deprecated/app/util.py | 134 ------ openadapt/deprecated/app/visualize.py | 409 ------------------ openadapt/start.py | 3 - 7 files changed, 930 deletions(-) delete mode 100644 openadapt/deprecated/app/main.py delete mode 100644 openadapt/deprecated/app/objects/console.py delete mode 100644 openadapt/deprecated/app/objects/local_file_picker.py delete mode 100644 openadapt/deprecated/app/util.py delete mode 100644 openadapt/deprecated/app/visualize.py diff --git a/openadapt/deprecated/app/cards.py b/openadapt/deprecated/app/cards.py index 8a276eb44..18f11e69a 100644 --- a/openadapt/deprecated/app/cards.py +++ b/openadapt/deprecated/app/cards.py @@ -7,10 +7,6 @@ import multiprocessing import time -from nicegui import ui - -from openadapt.deprecated.app.objects.local_file_picker import LocalFilePicker -from openadapt.deprecated.app.util import get_scrub, set_dark, set_scrub, sync_switch from openadapt.record import record from openadapt.utils import WrapStdout @@ -67,55 +63,6 @@ def start(self, func: callable, args: tuple, kwargs: dict) -> None: record_proc = RecordProc() -def settings(dark_mode: bool) -> None: - """Display the settings dialog. - - Args: - dark_mode (bool): Current dark mode setting. - """ - with ui.dialog() as settings, ui.card(): - dark_switch = ui.switch( - "Dark mode", on_change=lambda: set_dark(dark_mode, dark_switch.value) - ) - sync_switch(dark_switch, dark_mode) - - scrub_switch = ui.switch( - "Scrubbing", on_change=lambda: set_scrub(scrub_switch.value) - ) - sync_switch(scrub_switch, get_scrub()) - - ui.button("Close", on_click=lambda: settings.close()) - settings.open() - - -def select_import(f: callable) -> None: - """Display the import file selection dialog. - - Args: - f (callable): Function to call when import button is clicked. - """ - - async def pick_file() -> None: - result = await LocalFilePicker(".") - ui.notify(f"Selected {result[0]}" if result else "No file selected.") - selected_file.text = result[0] if result else "" - import_button.enabled = True if result else False - - with ui.dialog() as import_dialog, ui.card(): - with ui.column(): - ui.button("Select File", on_click=pick_file).props("icon=folder") - selected_file = ui.label("") - selected_file.visible = False - import_button = ui.button( - "Import", - on_click=lambda: f(selected_file.text, delete.value), - ) - import_button.enabled = False - delete = ui.checkbox("Delete file after import") - - import_dialog.open() - - def stop_record() -> None: """Stop the current recording session.""" global record_proc @@ -152,60 +99,3 @@ def quick_record( "log_memory": False, }, ) - - -def recording_prompt(options: list[str], record_button: ui.button) -> None: - """Display the recording prompt dialog. - - Args: - options (list): List of autocomplete options. - record_button (nicegui.widgets.Button): Record button widget. - """ - if not record_proc.is_running(): - with ui.dialog() as dialog, ui.card(): - ui.label("Enter a name for the recording: ") - ui.input( - label="Name", - placeholder="test", - autocomplete=options, - on_change=lambda e: result.set_text(e), - ) - result = ui.label() - - with ui.row(): - ui.button("Close", on_click=dialog.close) - ui.button("Enter", on_click=lambda: on_record()) - - dialog.open() - - def terminate() -> None: - global record_proc - record_proc.set_terminate_processing() - - # wait for process to terminate - record_proc.wait() - ui.notify("Stopped recording") - record_button._props["name"] = "radio_button_checked" - record_button.on("click", lambda: recording_prompt(options, record_button)) - - record_proc.reset() - - def begin() -> None: - name = result.text.__getattribute__("value") - - ui.notify( - f"Recording {name}... Press CTRL + C in terminal window to cancel", - ) - global record_proc - record_proc.start( - record, - (name, record_proc.terminate_processing, record_proc.terminate_recording), - ) - record_button._props["name"] = "stop" - record_button.on("click", lambda: terminate()) - record_button.update() - - def on_record() -> None: - global record_proc - dialog.close() - begin() diff --git a/openadapt/deprecated/app/main.py b/openadapt/deprecated/app/main.py deleted file mode 100644 index 38388ca9a..000000000 --- a/openadapt/deprecated/app/main.py +++ /dev/null @@ -1,100 +0,0 @@ -"""openadapt.deprecated.app.main module. - -This module provides the main entry point for running the OpenAdapt application. - -Example usage: - from openadapt.deprecated.app import run_app - - run_app() -""" - -from functools import partial -from subprocess import Popen -import base64 -import os -import pathlib - -from nicegui import app, ui - -from openadapt import replay -from openadapt.config import config -from openadapt.deprecated.app.cards import recording_prompt, select_import, settings -from openadapt.deprecated.app.objects.console import Console -from openadapt.deprecated.app.util import clear_db, on_export, on_import - -SERVER = "127.0.0.1:8000/upload" -FPATH = pathlib.Path(__file__).parent - -# Recording description autocomplete -OPTIONS = ["test"] - -app.native.start_args["debug"] = False - -dark = ui.dark_mode() -dark.value = config.APP_DARK_MODE - -logger = None - - -def start(fullscreen: bool = False) -> None: - """Start the OpenAdapt application.""" - with ui.row().classes("w-full justify-right"): - with ui.avatar(color="white" if dark else "black", size=128): - logo_base64 = base64.b64encode( - open(os.path.join(FPATH, "assets/logo.png"), "rb").read() - ) - img = bytes( - f"data:image/png;base64,{(logo_base64.decode('utf-8'))}", - encoding="utf-8", - ) - ui.image(img.decode("utf-8")) - ui.icon("settings").tooltip("Settings").on("click", lambda: settings(dark)) - ui.icon("delete").on("click", lambda: clear_db(log=logger)).tooltip( - "Clear all recorded data" - ) - ui.icon("upload").tooltip("Export Data").on("click", lambda: on_export(SERVER)) - ui.icon("download").tooltip("Import Data").on( - "click", lambda: select_import(on_import) - ) - ui.icon("share").tooltip("Share").on( - "click", lambda: (_ for _ in ()).throw(Exception(NotImplementedError)) - ) - - with ui.splitter(value=20) as splitter: - splitter.classes("w-full h-full") - with splitter.before: - with ui.column().classes("w-full h-full"): - record_button = ( - ui.icon("radio_button_checked", size="64px") - .on( - "click", - lambda: recording_prompt(OPTIONS, record_button), - ) - .tooltip("Record a new replay / Stop recording") - ) - ui.icon("visibility", size="64px").on( - "click", partial(Popen, ["python", "-m", "openadapt.visualize"]) - ).tooltip("Visualize the latest replay") - - ui.icon("play_arrow", size="64px").on( - "click", - lambda: replay.replay("NaiveReplayStrategy"), - ).tooltip("Play the latest replay") - with splitter.after: - logger = Console() - logger.log.style("height: 250px;, width: 300px;") - - splitter.enabled = False - - ui.run( - title="OpenAdapt Client", - native=True, - window_size=(400, 400), - fullscreen=fullscreen, - reload=False, - show=False, - ) - - -if __name__ == "__main__": - start() diff --git a/openadapt/deprecated/app/objects/console.py b/openadapt/deprecated/app/objects/console.py deleted file mode 100644 index f01293a95..000000000 --- a/openadapt/deprecated/app/objects/console.py +++ /dev/null @@ -1,42 +0,0 @@ -"""openadapt.deprecated.app.objects.console module. - -This module provides the Console class for redirecting stderr to a NiceGUI log. - -Example usage: - logger = Console() - logger.write("Error message") -""" - -import sys - -from nicegui import ui - - -class Console(object): - """Console class for redirecting stderr to a NiceGUI log.""" - - def __init__(self) -> None: - """Initialize the Console object.""" - self.log = ui.log().classes("w-full h-20") - self.old_stderr = sys.stderr - self.buffer = "" - - def write(self, data: str) -> None: - """Write data to the log. - - Args: - data (str): Data to be written. - """ - self.log.push(data[:-1]) - self.log.update() - self.old_stderr.write(data) - - def flush(self) -> None: - """Flush the log.""" - self.log.update() - self.old_stderr.flush() - - def reset(self) -> None: - """Reset the log and restore stderr.""" - self.log.clear() - sys.stderr = self.old_stderr diff --git a/openadapt/deprecated/app/objects/local_file_picker.py b/openadapt/deprecated/app/objects/local_file_picker.py deleted file mode 100644 index 512ef3c5b..000000000 --- a/openadapt/deprecated/app/objects/local_file_picker.py +++ /dev/null @@ -1,132 +0,0 @@ -"""openadapt.deprecated.app.objects.local_file_picker module. - -This module provides the LocalFilePicker class for selecting - a file from the local filesystem. -# retrieved from -https://github.com/zauberzeug/nicegui/tree/main/examples/local_file_picker - -Example usage: - from openadapt.deprecated.app.objects.local_file_picker import LocalFilePicker - - async def pick_file(): - result = await LocalFilePicker("~", multiple=True) - ui.notify(f"You chose {result}") -""" - -from pathlib import Path -from typing import Dict, Optional - -from nicegui import ui - - -class LocalFilePicker(ui.dialog): - """LocalFilePicker class for selecting a file from the local filesystem.""" - - def __init__( - self, - directory: str, - *, - upper_limit: Optional[str] = ..., - multiple: bool = False, - show_hidden_files: bool = False, - dark_mode: bool = False, - ) -> None: - """Initialize the LocalFilePicker object. - - Args: - directory (str): The directory to start in. - upper_limit (Optional[str]): The directory to stop at - (None: no limit, default: same as the starting directory). - multiple (bool): Whether to allow multiple files to be selected. - show_hidden_files (bool): Whether to show hidden files. - dark_mode (bool): Whether to use dark mode for the file picker. - """ - super().__init__() - - self.path = Path(directory).expanduser() - if upper_limit is None: - self.upper_limit = None - else: - self.upper_limit = Path( - directory if upper_limit == ... else upper_limit - ).expanduser() - self.show_hidden_files = show_hidden_files - - with self, ui.card(): - self.grid = ( - ui.aggrid( - { - "columnDefs": [{"field": "name", "headerName": "File"}], - "rowSelection": "multiple" if multiple else "single", - }, - html_columns=[0], - ) - .classes("w-96") - .on("cellDoubleClicked", self.handle_double_click) - ) - with ui.row().classes("w-full justify-end"): - ui.button("Cancel", on_click=self.close).props("outline") - ui.button("Ok", on_click=self._handle_ok) - self.update_grid() - - def update_grid(self) -> None: - """Update the grid with file data.""" - paths = list(self.path.glob("*")) - if not self.show_hidden_files: - paths = [p for p in paths if not p.name.startswith(".")] - paths.sort(key=lambda p: p.name.lower()) - paths.sort(key=lambda p: not p.is_dir()) - - self.grid.options["rowData"] = [ - { - "name": f"📁 {p.name}" if p.is_dir() else p.name, - "path": str(p), - } - for p in paths - ] - if ( - self.upper_limit is None - and self.path != self.path.parent - or self.upper_limit is not None - and self.path != self.upper_limit - ): - self.grid.options["rowData"].insert( - 0, - { - "name": "📁 ..", - "path": str(self.path.parent), - }, - ) - - self.grid.update() - - async def handle_double_click(self, msg: Dict) -> None: - """Handle the double-click event on a cell in the grid. - - Args: - msg (Dict): Message containing the event data. - """ - self.path = Path(msg["args"]["data"]["path"]) - if self.path.is_dir(): - self.update_grid() - else: - self.submit([str(self.path)]) - - async def _handle_ok(self) -> None: - """Handle the Ok button click event.""" - rows = await ui.run_javascript( - f"getElement({self.grid.id}).gridOptions.api.getSelectedRows()" - ) - self.submit([r["path"] for r in rows]) - - -async def pick_file() -> None: - """Async function for picking a file using LocalFilePicker.""" - result = await LocalFilePicker("~", multiple=True) - ui.notify(f"You chose {result}") - - -if __name__ in {"__main__", "__mp_main__"}: - ui.button("Choose file", on_click=pick_file).props("icon=folder") - - ui.run(native=True) diff --git a/openadapt/deprecated/app/util.py b/openadapt/deprecated/app/util.py deleted file mode 100644 index f73c18974..000000000 --- a/openadapt/deprecated/app/util.py +++ /dev/null @@ -1,134 +0,0 @@ -"""openadapt.deprecated.app.util module. - -This module provides utility functions for the OpenAdapt application. - -Example usage: - from openadapt.deprecated.app.util import clear_db, on_import, on_export, sync_switch, set_dark - - clear_db() - on_import(selected_file, delete=False, src="openadapt.db") - on_export(dest) - sync_switch(switch, prop) - set_dark(dark_mode, value) -""" - -from shutil import copyfileobj -import bz2 -import os -import sys - -from nicegui import elements, ui - -from openadapt.config import config -from openadapt.deprecated.app.objects import console -from openadapt.scripts.reset_db import reset_db - - -def clear_db(log: console.Console) -> None: - """Clear the database. - - Args: - log: Optional NiceGUI log object. - """ - if log: - log.log.clear() - o = sys.stdout - sys.stdout = sys.stderr - - reset_db() - ui.notify("Cleared database.") - sys.stdout = o - - -def on_import( - selected_file: str, - delete: bool = False, - src: str = "openadapt.db", -) -> None: - """Import data from a selected file. - - Args: - selected_file (str): The path of the selected file. - delete (bool): Whether to delete the selected file after import. - src (str): The source file name to save the imported data. - """ - with open(src, "wb") as f: - with bz2.BZ2File(selected_file, "rb") as f2: - copyfileobj(f2, f) - - if delete: - os.remove(selected_file) - - ui.notify("Imported data.") - - -def on_export(dest: str) -> None: - """Export data to a destination. - - Args: - dest (str): The destination to export the data to. - """ - # TODO: add ui card for configuration - ui.notify("Exporting data...") - - # compress db with bz2 - with open("openadapt.db", "rb") as f: - with bz2.BZ2File("openadapt.db.bz2", "wb", compresslevel=9) as f2: - copyfileobj(f, f2) - - # TODO: magic wormhole - # # upload to server with requests, and keep file name - # files = { - # "files": open("openadapt.db.bz2", "rb"), - # } - # #requests.post(dest, files=files) - - # delete compressed db - os.remove("openadapt.db.bz2") - - ui.notify("Exported data.") - - -def sync_switch( - switch: elements.switch.Switch, prop: elements.mixins.value_element.ValueElement -) -> None: - """Synchronize the value of a switch with a property. - - Args: - switch: The switch object. - prop: The property object. - """ - switch.value = prop.value if hasattr(prop, "value") else prop - - -def set_scrub(value: bool) -> None: - """Set the scrubbing value. - - Args: - value: The value to set. - """ - if config.SCRUB_ENABLED != value: - config.SCRUB_ENABLED = value - ui.notify("Scrubbing enabled." if value else "Scrubbing disabled.") - ui.notify("You may need to restart the app for this to take effect.") - - -def get_scrub() -> bool: - """Get the scrubbing value. - - Returns: - bool: The scrubbing value. - """ - return config.SCRUB_ENABLED - - -def set_dark(dark_mode: ui.dark_mode, value: bool) -> None: - """Set the dark mode. - - Args: - dark_mode: The dark mode object. - value: The value to set. - """ - if dark_mode.value != value: - dark_mode.value = value - config.APP_DARK_MODE = value diff --git a/openadapt/deprecated/app/visualize.py b/openadapt/deprecated/app/visualize.py deleted file mode 100644 index 44f86b42c..000000000 --- a/openadapt/deprecated/app/visualize.py +++ /dev/null @@ -1,409 +0,0 @@ -"""Implements visualization utilities for OpenAdapt.""" - -from base64 import b64encode -from functools import partial -from os import path, sep -from pprint import pformat - -from nicegui import events, ui - -from openadapt.build_utils import redirect_stdout_stderr -from openadapt.custom_logger import logger - -with redirect_stdout_stderr(): - from tqdm import tqdm - -import click - -from openadapt.config import config -from openadapt.db import crud -from openadapt.events import get_events -from openadapt.plotting import display_event, plot_performance -from openadapt.utils import EMPTY, configure_logging, image2utf8, row2dict, rows2dicts - -SCRUB = config.SCRUB_ENABLED - -if SCRUB: - # too many warnings from scrubbing - __import__("warnings").filterwarnings("ignore", category=DeprecationWarning) - from openadapt.privacy.providers.presidio import PresidioScrubbingProvider - - scrub = PresidioScrubbingProvider() - - -LOG_LEVEL = "INFO" -MAX_EVENTS = None -PROCESS_EVENTS = True - -performance_plot_img: ui.interactive_image = None - - -def create_tree( - tree_dict: dict, max_children: str = config.VISUALIZE_MAX_TABLE_CHILDREN -) -> list[dict]: - """Recursively creates a tree from a dictionary. - - Args: - tree_dict (dict): The dictionary to create a tree from. - max_children (str, optional): The maximum number of children to display. - Defaults to MAX_TABLE_CHILDREN. - - Returns: - list[dict]: Data for a Quasar Tree. - """ - tree_data = [] - for key, value in tree_dict.items(): - if value in EMPTY: - continue - node = { - "id": ( - str(key) - + f"{(': ' + str(value)) if not isinstance(value, (dict, list)) else ''}" # noqa - ) - } - if isinstance(value, dict): - node["children"] = create_tree(value) - elif isinstance(value, list): - if max_children is not None and len(value) > max_children: - node["children"] = create_tree( - {i: v for i, v in enumerate(value[:max_children])} - ) - node["children"].append({"id": "..."}) - else: - node["children"] = create_tree({i: v for i, v in enumerate(value)}) - tree_data.append(node) - return tree_data - - -def set_tree_props(tree: ui.tree) -> None: - """Sets properties for a UI tree based on values from config. - - Args: - tree (ui.tree): A Quasar Tree. - """ - tree._props["dense"] = config.VISUALIZE_DENSE_TREES - tree._props["no-transition"] = not config.VISUALIZE_ANIMATIONS - tree._props["default-expand-all"] = config.VISUALIZE_EXPAND_ALL - tree._props["filter"] = "" - - -def set_filter( - text: str, - tree: ui.tree, -) -> None: - """Sets filter for UI trees. - - Args: - tree (ui.tree): A Quasar Tree. - text (str): The text to filter by. - """ - tree._props["filter"] = text - tree.update() - - -def toggle_dark_mode( - ui_dark: ui.dark_mode, plots: tuple[str], curr_logo: ui.image, images: tuple[str] -) -> None: - """Handles dark mode toggle. - - Args: - ui_dark (ui.dark_mode): The dark mode switch. - plots (tuple[str]): The performance plots. - curr_logo (ui.image): The current logo. - images (tuple[str]): The light and dark mode logos (decoded) - """ - global performance_plot_img - ui_dark.toggle() - ui_dark.update() - config.VISUALIZE_DARK_MODE = ui_dark.value - curr_logo.source = images[int(ui_dark.value)] - curr_logo.update() - performance_plot_img.source = plots[int(ui_dark.value)] - performance_plot_img.update() - - -@logger.catch -@click.command() -@click.option( - "--timestamp", - type=str, - help="The timestamp of the recording to visualize.", -) -def main(timestamp: str) -> None: - """Visualize a recording.""" - configure_logging(logger, LOG_LEVEL) - - ui_dark = ui.dark_mode(config.VISUALIZE_DARK_MODE) - session = crud.get_new_session(read_only=True) - - if timestamp is None: - recording = crud.get_latest_recording(session) - else: - recording = crud.get_recording(session, timestamp) - - if SCRUB: - scrub.scrub_text(recording.task_description) - logger.debug(f"{recording=}") - - meta = {} - action_events = get_events(session, recording, process=PROCESS_EVENTS, meta=meta) - event_dicts = rows2dicts(action_events) - - if SCRUB: - event_dicts = scrub.scrub_list_dicts(event_dicts) - logger.info(f"event_dicts=\n{pformat(event_dicts)}") - - recording_dict = row2dict(recording) - - if SCRUB: - recording_dict = scrub.scrub_dict(recording_dict) - - # setup tables for recording / metadata - recording_column = [ - ( - { - "name": key, - "field": key, - "label": key, - "sortable": False, - "required": False, - "align": "left", - } - ) - for key in recording_dict.keys() - ] - - meta_col = [ - { - "name": key, - "field": key, - "label": key, - "sortable": False, - "required": False, - "align": "left", - } - for key in meta.keys() - ] - - plots = ( - plot_performance(recording, save_file=False, view_file=False), - plot_performance(recording, save_file=False, view_file=False, dark_mode=True), - ) - - with ui.row(): - with ui.avatar(color="auto", size=128): - images = () - - # generate base64 encoded images for light and dark mode - for i in range(2): - fp = f"{path.dirname(__file__)}{sep}assets{sep}logo" - logo_base64 = b64encode( - open( - f"{fp}{'_inverted' if i > 0 else ''}.png", - "rb", - ).read() - ) - images += ( - bytes( - f"data:image/png;base64,{(logo_base64.decode('utf-8'))}", - encoding="utf-8", - ).decode("utf-8"), - ) - curr_logo = ui.image(images[int(ui_dark.value)]) - ui.switch( - text="Dark Mode", - value=ui_dark.value, - on_change=partial(toggle_dark_mode, ui_dark, plots, curr_logo, images), - ) - - # create splitter with recording info on left and performance plot on right - with ui.splitter(value=20).style("flex-wrap: nowrap;") as splitter: - splitter._props["limits"] = [20, 80] - - # TODO: find a way to set "overflow: hidden;" for the splitter - with splitter.before: - ui.table(rows=[meta], columns=meta_col).style("min-width: 50em;")._props[ - "grid" - ] = True - with splitter.after: - global performance_plot_img - performance_plot_img = ui.interactive_image( - source=plots[int(ui_dark.value)] - ) - with performance_plot_img: - # ui.button( - # on_click=lambda: plot_performance( - # recording.timestamp, view_file=True, save_file=False - # ), - # icon="visibility", - # ).props("flat fab").tooltip("View") - - ui.button( - on_click=lambda: plot_performance( - recording, - save_file=True, - view_file=False, - dark_mode=ui_dark.value, - ), - icon="save", - ).props("flat fab").tooltip("Save as PNG") - - ui.table(rows=[recording_dict], columns=recording_column) - - interactive_images = [] - action_event_trees = [] - window_event_trees = [] - text_inputs = [] - - logger.info(f"{len(action_events)=}") - - num_events = ( - min(MAX_EVENTS, len(action_events)) - if MAX_EVENTS is not None - else len(action_events) - ) - - # global search - def on_change_closure(e: events.ValueChangeEventArguments) -> None: - for tree in range(len(action_event_trees)): - set_filter( - e.value, - action_event_trees[tree], - ) - set_filter( - e.value, - window_event_trees[tree], - ) - - text_inputs.append( - ui.input( - label="search all", - placeholder="filter all", - on_change=partial(on_change_closure), - ).tooltip( - "this will search all trees, but can be overridden by individual filters" - ) - ) - - with redirect_stdout_stderr(): - with tqdm( - total=num_events, - desc="Generating Visualization" if not SCRUB else "Scrubbing Visualization", - unit="event", - colour="green", - dynamic_ncols=True, - ) as progress: - for idx, action_event in enumerate(action_events): - if idx == MAX_EVENTS: - break - - image = display_event(action_event) - # diff = display_event(action_event, diff=True) - # mask = action_event.screenshot.diff_mask - - if SCRUB: - image = scrub.scrub_image(image) - # diff = scrub.scrub_image(diff) - # mask = scrub.scrub_image(mask) - - image_utf8 = image2utf8(image) - # diff_utf8 = image2utf8(diff) - # mask_utf8 = image2utf8(mask) - width, height = image.size - - action_event_dict = row2dict(action_event) - window_event_dict = row2dict(action_event.window_event) - - if SCRUB: - action_event_dict = scrub.scrub_dict(action_event_dict) - window_event_dict = scrub.scrub_dict(window_event_dict) - - with ui.column(): - with ui.row(): - interactive_images.append( - ui.interactive_image( - source=image_utf8, - ).classes("drop-shadow-md rounded") - ) - with ui.splitter(value=60) as splitter: - splitter.classes("w-full h-full") - with splitter.after: - ui.label("action_event_dict").style("font-weight: bold;") - - def on_change_closure( - e: events.ValueChangeEventArguments, idx: int - ) -> None: - return set_filter( - e.value, - action_event_trees[idx], - ) - - text_inputs.append( - ui.input( - label="search", - placeholder="filter", - on_change=partial( - on_change_closure, - idx=idx, - ), - ) - ) - ui.html("
") - action_event_tree = create_tree(action_event_dict) - action_event_trees.append( - ui.tree( - action_event_tree, - label_key="id", - # on_select=lambda e: ui.notify(e.value), - ) - ) - set_tree_props(action_event_trees[idx]) - with splitter.before: - ui.label("window_event_dict").style("font-weight: bold;") - - def on_change_closure( - e: events.ValueChangeEventArguments, idx: int - ) -> None: - return set_filter( - e.value, - window_event_trees[idx], - ) - - text_inputs.append( - ui.input( - label="search", - placeholder="filter", - on_change=partial( - on_change_closure, - idx=idx, - ), - ) - ) - ui.html("
") - window_event_tree = create_tree(window_event_dict, None) - - window_event_trees.append( - ui.tree( - window_event_tree, - label_key="id", - # on_select=lambda e: ui.notify(e.value), - ) - ) - - set_tree_props(window_event_trees[idx]) - - progress.update() - - progress.close() - - ui.run( - reload=False, - title=f"OpenAdapt: recording-{recording.id}", - favicon="📊", - native=config.VISUALIZE_RUN_NATIVELY, - fullscreen=config.VISUALIZE_RUN_NATIVELY, - ) - - -if __name__ == "__main__": - main() diff --git a/openadapt/start.py b/openadapt/start.py index 0b323653d..af22ef99d 100644 --- a/openadapt/start.py +++ b/openadapt/start.py @@ -7,7 +7,6 @@ import subprocess from openadapt.custom_logger import logger -from openadapt.deprecated.app.main import run_app def main() -> None: @@ -24,8 +23,6 @@ def main() -> None: subprocess.run(["git", "pull", "-q"]) logger.info("Updated the OpenAdapt App") - run_app() # start gui - if __name__ == "__main__": main()