plesty.server.view.dialogs ========================== .. py:module:: plesty.server.view.dialogs .. autoapi-nested-parse:: The console's pop-up views: declare a device, run a field test, follow a job. Each dialog collects an intent and turns it into a model object (:class:`DeviceSpec`, :class:`FieldTestRun`); the window hands that to the presenter. :class:`JobDialog` is the one that renders as it goes: it tails a job log through the presenter until the job ends. Classes ------- .. autoapisummary:: plesty.server.view.dialogs.DeclareDialog plesty.server.view.dialogs.FieldTestDialog plesty.server.view.dialogs.JobDialog plesty.server.view.dialogs.DeviceConfigDialog plesty.server.view.dialogs.FleetFileDialog plesty.server.view.dialogs.CatalogueDialog Functions --------- .. autoapisummary:: plesty.server.view.dialogs.confirm plesty.server.view.dialogs.alert plesty.server.view.dialogs.about Module Contents --------------- .. py:class:: DeclareDialog(parent: PySide6.QtWidgets.QWidget | None = None, spec: plesty.server.model.DeviceSpec | None = None, options: plesty.server.presenter.SourceOptions | None = None, packages: tuple[str, Ellipsis] = (), options_for: collections.abc.Callable[[str], plesty.server.presenter.SourceOptions] | None = None, info_for: collections.abc.Callable[[str], Any] | None = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Add (or edit) a device declaration. The source is one of two, never both: a **release** (PyPI, pinned to a version or the newest) or a **repository** (git URL at a ref). The version and ref fields are editable drop-downs filled from what the bench knows (:class:`SourceOptions`); anything else can be typed. Build the form. :param parent: Qt parent. :param spec: The declaration to edit; ``None`` declares a new device. :param options: Drop-down contents for the (initial) package. :param packages: Installed modules a *new* device may be declared from — the only choices; the catalogue installs new ones. :param options_for: Returns the drop-down contents for a package, called when the user picks another one. :param info_for: Returns the package-level record (repository, latest release) shown read-only under the package. .. py:attribute:: _options_for :value: None .. py:attribute:: _info_for :value: None .. py:attribute:: name .. py:attribute:: _proposed .. py:attribute:: package .. py:attribute:: release_radio .. py:attribute:: repo_radio .. py:attribute:: _source_group .. py:attribute:: version .. py:attribute:: git .. py:attribute:: ref .. py:attribute:: args .. py:attribute:: env .. py:attribute:: autostart .. py:attribute:: project .. py:attribute:: hint .. py:attribute:: error .. py:attribute:: _spec :type: plesty.server.model.DeviceSpec | None :value: None .. py:property:: repository_mode :type: bool Whether the repository source is selected (else the release). .. py:property:: package_name :type: str The package the declaration names. .. py:method:: show_project(info: Any) -> None Show the package's project page and latest release (a ``PackageInfo``). .. py:method:: _package_changed(package: str) -> None Refill the version/ref/url drop-downs (and the project line) for another package. .. py:method:: _source_changed(*_args: object) -> None .. py:method:: to_spec() -> plesty.server.model.DeviceSpec The declaration the form describes. :raises FleetError: When a field is malformed. .. py:property:: spec :type: plesty.server.model.DeviceSpec | None The accepted declaration, or ``None`` when cancelled. .. py:method:: _accept() -> None .. py:class:: FieldTestDialog(name: str, parent: PySide6.QtWidgets.QWidget | None = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Configure a field-test run for one device. The gates are the standard plesty-lib field-test gates as check boxes (all checked = the script's default: run everything); a script's own ``--help`` may narrow the list once the window has fetched it. Build the form for device *name*. .. py:attribute:: tier .. py:attribute:: address .. py:attribute:: gate_boxes :type: dict[str, PySide6.QtWidgets.QCheckBox] .. py:attribute:: gates_box .. py:attribute:: _gates_layout .. py:attribute:: repetitions .. py:attribute:: keep_going .. py:attribute:: keep_server .. py:attribute:: extra .. py:attribute:: options_label .. py:attribute:: error .. py:attribute:: _run :type: plesty.server.model.FieldTestRun | None :value: None .. py:method:: _set_gates(gates: list[str]) -> None Rebuild the gate check boxes (all checked). .. py:method:: show_options(info: dict[str, list[str]]) -> None Show what the device's script accepts (fetched by the window off the GUI thread). .. py:property:: selected_gates :type: tuple[str, Ellipsis] | None The checked gates in order, or ``None`` when all are checked (= run everything). .. py:method:: to_run() -> plesty.server.model.FieldTestRun The request the form describes. :raises FleetError: When a field is malformed (e.g. no gate checked). .. py:property:: run :type: plesty.server.model.FieldTestRun | None The accepted request, or ``None`` when cancelled. .. py:method:: _accept() -> None .. py:class:: JobDialog(bench: plesty.server.presenter.Bench, job: plesty.server.model.Job, parent: PySide6.QtWidgets.QWidget | None = None, poll_ms: int = 400, on_finished: collections.abc.Callable[[plesty.server.model.Job], None] | None = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Follow one job: its log as it grows, its state, a cancel button. Start tailing *job* through *bench*. :param bench: The presenter. :param job: The job to follow. :param parent: Qt parent. :param poll_ms: Tail interval. :param on_finished: Called once, on the GUI thread, when the job ends. .. py:attribute:: bench .. py:attribute:: job .. py:attribute:: _offset :value: 0 .. py:attribute:: _on_finished :value: None .. py:attribute:: _finished :value: False .. py:attribute:: state .. py:attribute:: log .. py:attribute:: cancel_button .. py:attribute:: close_button .. py:attribute:: _timer .. py:method:: poll() -> None Read new log text and the job state; stop polling when it ended. .. py:method:: _cancel() -> None .. py:function:: confirm(parent: PySide6.QtWidgets.QWidget | None, title: str, text: str) -> bool A yes/no question; ``True`` when confirmed. .. py:function:: alert(parent: PySide6.QtWidgets.QWidget | None, title: str, text: str) -> None Show an error. .. py:function:: about(parent: PySide6.QtWidgets.QWidget | None, version: str) -> None The About box, with the PLESTY mark. .. py:class:: DeviceConfigDialog(bench: plesty.server.presenter.Bench, name: str, parent: PySide6.QtWidgets.QWidget | None = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Edit → Device config…: the declaration and the ``.env`` file of one device, tabbed. Build the dialog for device *name* on *bench*. .. py:attribute:: bench .. py:attribute:: name .. py:attribute:: declare .. py:attribute:: env .. py:attribute:: env_highlighter .. py:attribute:: tabs .. py:attribute:: error .. py:method:: _save() -> None .. py:class:: FleetFileDialog(bench: plesty.server.presenter.Bench, parent: PySide6.QtWidgets.QWidget | None = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Edit → Fleet file…: the fleet as YAML, validated before it is written. Show the current fleet text of *bench*. .. py:attribute:: bench .. py:attribute:: editor .. py:attribute:: error .. py:method:: _save() -> None .. py:class:: CatalogueDialog(bench: plesty.server.presenter.Bench, parent: PySide6.QtWidgets.QWidget | None = None, worker: Any = None) Bases: :py:obj:`PySide6.QtWidgets.QDialog` Catalogue → Search & install…: the hub's device modules, put on this bench. A market place, and nothing more: installing from it stocks the bench with a module. No device is declared and no fleet file is touched — Edit ▸ Add device… does that, choosing from what the bench holds. The source is the one the bench can carry out: a **release** from PyPI, which needs only ``uv``, or the **repository** at a ref, which needs git. Which of the two a module offers is what PyPI is asked on selection. Build the dialog; the catalogue is fetched on :meth:`load`. :param bench: The presenter. :param parent: Qt parent. :param worker: Runs the PyPI lookup off the GUI thread; without one it is done in place (tests). .. py:attribute:: bench .. py:attribute:: _entries :type: list[Any] :value: [] .. py:attribute:: _shown :type: list[Any] :value: [] .. py:attribute:: _releases :type: dict[str, str | None] .. py:attribute:: _worker :value: None .. py:attribute:: _item_type .. py:attribute:: query .. py:attribute:: vendor .. py:attribute:: table .. py:attribute:: release_radio .. py:attribute:: repo_radio .. py:attribute:: _source_group .. py:attribute:: version .. py:attribute:: ref .. py:attribute:: source_note .. py:attribute:: install_button .. py:attribute:: status .. py:attribute:: error .. py:attribute:: selected_entry :type: Any :value: None .. py:attribute:: started_job :type: plesty.server.model.Job | None :value: None .. py:method:: load(entries: list[Any]) -> None Show *entries* (fetched by the caller, off the GUI thread). .. py:method:: apply_filter() -> None Repaint the table for the current query and vendor. .. py:method:: _on_bench(package: str) -> str What this bench already holds of *package*: versions and refs, or ``—``. .. py:method:: _selection_changed() -> None .. py:method:: _ask_pypi(package: str) -> None Look up the newest release of *package*, off the GUI thread when it can. .. py:method:: _show_source(package: str, release: str | None) -> None Select the source the bench can carry out, and say why it is that one. .. py:method:: _source_changed() -> None .. py:method:: _install() -> None