Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
55 changes: 30 additions & 25 deletions ait/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import webbrowser

import bottle
import pkg_resources

import ait.core
from ait.core import (
Expand Down Expand Up @@ -185,8 +184,8 @@
A Playback manages the state for the playback component.
playback.dbconn: connection to database
playback.query: time query map of {timestamp: list of (uid, data)} from database
playback.on: True if gui is currently in playback mode. Real-time telemetry will not
be sent to the frontend during this.
playback.on: True if gui is currently in playback mode.
Real-time telemetry will not be sent to the frontend during this.
playback.enabled: True if historical data playback is enabled. This will be False
if a database connection cannot be made or if data playback is disabled for
some other reason.
Expand Down Expand Up @@ -214,7 +213,7 @@
for i in range(len(plugins)):
if (
plugins[i]["plugin"]["name"]
== "ait.core.server.plugins.data_archive.DataArchive"
== "ait.core.server.plugins.data_archive.DataArchive" # noqa: W503
):
datastore = plugins[i]["plugin"]["datastore"]
other_args = copy.deepcopy(plugins[i]["plugin"])
Expand Down Expand Up @@ -252,13 +251,14 @@
Sessions = SessionStore()
playback = Playback()


_RUNNING_SCRIPT = None
_RUNNING_SEQ = None
CMD_API = ait.core.api.CmdAPI()


class HTMLRoot:
Static = User = pkg_resources.resource_filename("ait.gui", "static/")
Static = User = str(importlib.resources.files("ait.gui").joinpath("static/"))


SEQRoot = ait.config.get("sequence.directory", None) # type: ignore[attr-defined]
Expand Down Expand Up @@ -299,14 +299,14 @@
try:
HTMLRoot.User = kwargs["html"]["directory"]
log.info(
"[GUI Plugin Configuration] Static file directory is set to {}".format(
HTMLRoot.User
)
"[GUI Plugin Configuration] Static file directory "
"is set to {}".format(HTMLRoot.User)
)
# TODO: Fix this nonsense
except Exception:
log.warn(
"[GUI Plugin Configuration] Unable to locate static file directory in config.yaml. "
"[GUI Plugin Configuration] Unable to locate static "
"file directory in config.yaml. "
"The directory is set to {}".format(HTMLRoot.User)
)

Expand Down Expand Up @@ -578,13 +578,15 @@
type: "MSB_U16",
bytes: [2, 3],
name: "Voltage_B",
desc: "Voltage B as a 14-bit DN. Conversion to engineering units is TBD."
desc: "Voltage B as a 14-bit DN. Conversion to
engineering units is TBD."
},
Voltage_C: {
type: "MSB_U16",
bytes: [4, 5],
name: "Voltage_C",
desc: "Voltage C as a 14-bit DN. Conversion to engineering units is TBD."
desc: "Voltage C as a 14-bit DN. Conversion to
engineering units is TBD."
},
...
}
Expand Down Expand Up @@ -785,8 +787,8 @@
for f in pkt_defn.fields:
if (
f.dntoeu is not None
or f.enum is not None
or f.type.name in dtype.ComplexTypeMap.keys()
or f.enum is not None # noqa: W503
or f.type.name in dtype.ComplexTypeMap.keys() # noqa: W503
):
try:
val = getattr(ait_pkt, f.name)
Expand Down Expand Up @@ -829,8 +831,8 @@

if (
field.dntoeu is not None
or field.enum is not None
or field.type.name in dtype.ComplexTypeMap.keys()
or field.enum is not None # noqa: W503
or field.type.name in dtype.ComplexTypeMap.keys() # noqa: W503
):
try:
dntoeu_val = getattr(ait_pkt, field.name)
Expand Down Expand Up @@ -971,7 +973,7 @@
"--csv",
os.path.join(HTMLRoot.Static, "query_out.csv"),
]
+ ["{}".format(p) for p in pcaps]
+ ["{}".format(p) for p in pcaps] # noqa: W503
)

os.remove(_fields_file_path)
Expand Down Expand Up @@ -1102,7 +1104,7 @@
"""
with Sessions.current() as session: # noqa: F841
script_path = os.path.join(ScriptRoot, urllib.parse.unquote(name))
if not os.path.exists(script_path):

Check warning on line 1107 in ait/gui/__init__.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Change this code to not construct the path from user-controlled data.

See more on https://sonarcloud.io/project/issues?id=NASA-AMMOS_AIT-GUI&issues=AZ0ruB7P7Lq6732fIKvZ&open=AZ0ruB7P7Lq6732fIKvZ&pullRequest=265
bottle.abort(400, "Script cannot be located")

with open(script_path) as infile:
Expand Down Expand Up @@ -1170,7 +1172,7 @@
script_exec_lock.acquire()

if _RUNNING_SCRIPT:
_RUNNING_SCRIPT.kill(UIAbortException())
_RUNNING_SCRIPT.kill(UIAbortError())
script_exec_lock.release()
Sessions.add_event("script:aborted", None)

Expand Down Expand Up @@ -1265,13 +1267,15 @@

@App.route("/playback/range", method="GET")
def handle_playback_range_get():
"""Return a JSON array of [packet_name, start_time, end_time] to represent the time range
of each packet in the database
"""Return a JSON array of [packet_name, start_time, end_time] to
represent the time range of each packet in the database
**Example Response**:
.. sourcecode: json
[
["1553_HS_Packet", "2019-07-15T18:10:00.0", "2019-07-15T18:12:00.0"],
["Ethernet_HS_Packet", "2019-07-15T19:25:16.0", "2019-07-15T19:28:50.0"],
["1553_HS_Packet", "2019-07-15T18:10:00.0",
"2019-07-15T18:12:00.0"],
["Ethernet_HS_Packet", "2019-07-15T19:25:16.0",
"2019-07-15T19:28:50.0"],
]
"""
global playback
Expand Down Expand Up @@ -1310,8 +1314,9 @@
end_time_str, "%Y-%m-%dT%H:%M:%SZ"
) + timedelta(seconds=1)
else:
end_time = datetime.strptime(end_time_str, "%Y-%m-%dT%H:%M:%S") + timedelta(
seconds=1
end_time = (
datetime.strptime(end_time_str, "%Y-%m-%dT%H:%M:%S")
+ timedelta(seconds=1) # noqa: W503
)

ranges[i].append(end_time.strftime("%Y-%m-%dT%H:%M:%SZ"))
Expand Down Expand Up @@ -1395,7 +1400,7 @@
session.telemetry.clear()


class UIAbortException(Exception):
class UIAbortError(Exception):
"""Raised when user aborts script execution via GUI controls"""

def __init__(self, msg=None):
Expand All @@ -1406,7 +1411,7 @@

@property
def msg(self):
s = "UIAbortException: User aborted script execution via GUI controls."
s = "UIAbortError: User aborted script execution via GUI controls."

if self._msg:
s += ": " + self._msg
Expand Down
1 change: 1 addition & 0 deletions ait/gui/bin/ait_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import struct
import time


def main():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
hs_packet = struct.Struct('>hhhhh')
Expand Down
11 changes: 8 additions & 3 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@

if os.getenv('READTHEDOCS'):
root_for_relative_js_paths = '../../ait/gui/static'
js_source_path = ['../../ait/gui/static/js/ait', '../../ait/gui/static/js/ait/gui']
else:
root_for_relative_js_paths = 'ait/gui/static'
js_source_path = ['ait/gui/static/js/ait', 'ait/gui/static/js/ait/gui']
import ait.gui
import os as _os
_static = _os.path.join(_os.path.dirname(ait.gui.__file__), 'static')
root_for_relative_js_paths = _static
js_source_path = [
_os.path.join(_static, 'js/ait'),
_os.path.join(_static, 'js/ait/gui')
]

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
Expand Down
2 changes: 2 additions & 0 deletions doc/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ AIT GUI Installation

This guide will show you how to install AIT GUI. It assumes that you have followed the `AIT Core Installation and Configuration Guide <https://ait-core.readthedocs.io/en/latest/installation.html>`_ and ended up with a working AIT Core install. You can install AIT GUI from a checkout of the code or from the AIT PyPi server. Having a checkout of the code can be handy if you want to view the source or make changes. Installing from PyPi keeps your system clutter free since you don't have a copy of the code base around. Either choice will work fine!

.. note:: AIT GUI is tested against Python 3.10, and 3.11. Python 3.11 is recommended for new installations.

From Code Checkout
------------------

Expand Down
Loading
Loading