Skip to content
Merged
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
39 changes: 15 additions & 24 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package

on:
release:
types: [published]
types:
- published

permissions:
contents: read

jobs:
deploy:

build-and-publish:
runs-on: ubuntu-latest

permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
run: python -m pip install -U setuptools wheel build
- name: Build
run: python -m build .
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
skip-existing: true
51 changes: 26 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,13 @@ Note that LEADS requires **Python >= 3.12**. To set up the environment on a Rasp
command, see [Environment Setup](#environment-setup).

```shell
pip install Pillow PySDL2 customtkinter gpiozero lgpio opencv-python-headless pynmea2 pynput pysdl2-dll pyserial screeninfo leads
pip install "leads[standard]"
```

`numpy` and `pandas` will be automatically installed with `leads`.

`Pillow`, `PySDL2`, `customtkinter`, `gpiozero`, `lgpio`, `opencv-python-headless`, `pynmea2`, `pynput`, `pysdl2-dll`,
`pyserial`, and `screeninfo` are optional.

If your platform does not support GPIO, just exclude `lgpio`.
If your platform does not support GPIO, use profile "no-gpio.

```shell
pip install Pillow PySDL2 customtkinter gpiozero opencv-python-headless pynmea2 pynput pysdl2-dll pyserial screeninfo leads
pip install "leads[no-gpio]"
```

If you only want the framework, run the following.
Expand All @@ -83,7 +78,7 @@ pip install leads
#### Verify

```shell
python -m leads_vec info
leads-vec info
```

### Arduino
Expand All @@ -101,21 +96,21 @@ the framework in your project.
### Main

```shell
python -m leads_vec run
leads-vec run
```

#### Optional Arguments

Run the following to get a list of all the supported arguments.

```shell
python -m leads_vec -h
leads-vec -h
```

##### Specify a Configuration File

```shell
python -m leads_vec -c path/to/the/config/file.json run
leads-vec -c path/to/the/config/file.json run
```

> You can use ":INTERNAL" to replace the path to `leads_vec`. For example, instead of typing
Expand All @@ -128,7 +123,7 @@ To learn about the configuration file, read [Configurations](#Configurations).
##### Specify a Devices Module

```shell
python -m leads_vec -d path/to/the/devices.py run
leads-vec -d path/to/the/devices.py run
```

> You can use ":INTERNAL" to replace the path to `leads_vec`. For example, instead of typing
Expand All @@ -139,7 +134,7 @@ To learn about the devices module, read [Devices Module](#devices-module).
##### Specify a Main Module

```shell
python -m leads_vec -m path/to/the/main.py run
leads-vec -m path/to/the/main.py run
```

> You can use ":INTERNAL" to replace the path to `leads_vec`. For example, instead of typing
Expand All @@ -160,15 +155,15 @@ def main() -> int:
##### Generate a Configuration File

```shell
python -m leads_vec -r config run
leads-vec -r config run
```

This will generate a default "config.json" file under the current directory.

##### Register a Systemd Service

```shell
python -m leads_vec -r systemd run
leads-vec -r systemd run
```

This will register a user Systemd service to start the program.
Expand All @@ -195,15 +190,15 @@ systemctl --user disable leads-vec
##### Use Reverse Proxy

```shell
python -m leads_vec -r reverse_proxy run
leads-vec -r reverse_proxy run
```

This will start the corresponding reverse proxy program as a subprocess in the background.

##### Specify a Theme

```shell
python -m leads_vec -t path/to/the/theme.json run
leads-vec -t path/to/the/theme.json run
```

> You can use ":INTERNAL" to replace the path to `leads_vec`. For example, instead of typing
Expand All @@ -214,32 +209,38 @@ To learn about themes, read [Color and Themes](https://customtkinter.tomschimans
##### Magnify Font Sizes

```shell
python -m leads_vec -mfs 1.5 run
leads-vec -mfs 1.5 run
```

This will magnify all font sizes by 1.5.

##### Use Emulation

```shell
python -m leads_vec --emu run
leads-vec --emu run
```

This will force the program to use emulation even if the environment is available.

##### Automatically Magnify Font Sizes

```shell
python -m leads_vec --auto-mfs run
leads-vec --auto-mfs run
```

Similar to [Magnify Font Sizes](#magnify-font-sizes), but instead of manually deciding the factor, the program will
automatically calculate the best factor to keep the original proportion as designed.

### Remote Analyst

The remote analyst requires additional dependencies. Install them through the following command.

```shell
pip install "leads[all]"
```

```shell
python -m leads_vec_rc
leads-vec-rc
```

Go to the online dashboard at https://leads-vec-rc.projectneura.org.
Expand All @@ -249,21 +250,21 @@ Go to the online dashboard at https://leads-vec-rc.projectneura.org.
Run the following to get a list of all the supported arguments.

```shell
python -m leads_vec_rc -h
leads-vec-rc -h
```

##### Server Port

```shell
python -m leads_vec_rc -p 80
leads-vec-rc -p 80
```

If not specified, the port is `8000` by default.

##### Specify a Configuration File

```shell
python -m leads_vec_rc -c path/to/the/config/file.json
leads-vec-rc -c path/to/the/config/file.json
```

If not specified, all configurations will be default values.
Expand Down
64 changes: 64 additions & 0 deletions leads_vec/__entry__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from argparse import ArgumentParser as _ArgumentParser, BooleanOptionalAction as _BooleanOptionalAction
from importlib.metadata import version as _package_version, PackageNotFoundError as _PackageNotFoundError
from os import getlogin as _get_login
from os.path import abspath as _abspath
from sys import exit as _exit, version as _version
from warnings import filterwarnings as _filterwarnings

from leads import L as _L
from leads_gui.system import get_system_kernel as _get_system_kernel
from leads_vec.run import run

MODULE_PATH = _abspath(__file__)[:-13]


def parse_path(path: str | None) -> str | None:
return path.replace(":INTERNAL", MODULE_PATH) if path else None


def __entry__() -> None:
_filterwarnings("ignore")

parser = _ArgumentParser(prog="LEADS VeC", description="Lightweight Embedded Assisted Driving System VeC",
epilog="Project Neura: https://projectneura.org\n"
"GitHub: https://github.com/ProjectNeura/LEADS")
parser.add_argument("action", choices=("info", "replay", "run"))
parser.add_argument("-c", "--config", default=None, help="specify a configuration file")
parser.add_argument("-d", "--devices", default=f"{MODULE_PATH}/devices.py", help="specify a devices module")
parser.add_argument("-m", "--main", default=f"{MODULE_PATH}/cli.py", help="specify a main module")
parser.add_argument("-r", "--register", choices=("systemd", "config", "reverse_proxy"), default=None,
help="register a service")
parser.add_argument("-t", "--theme", default=None, help="specify a theme")
parser.add_argument("-mfs", "--magnify-font-sizes", type=float, default=1, help="magnify font sizes by a factor")
parser.add_argument("--emu", action=_BooleanOptionalAction, default=False, help="use emulator")
parser.add_argument("--auto-mfs", action=_BooleanOptionalAction, default=False,
help="automatically magnify font sizes to match the original proportion")
parser.add_argument("--ignore-import-error", action=_BooleanOptionalAction, default=False,
help="ignore `ImportError`")
args = parser.parse_args()
if args.action == "info":
from leads_vec.__version__ import __version__
from ._bootloader import frpc_exists as _frpc_exists

leads_version = "Unknown"
try:
leads_version = _package_version("leads")
except _PackageNotFoundError:
_L.warn("Failed to retrieve package version (did you install through pip?)")
_L.info(f"LEADS VeC",
f"System Kernel: {_get_system_kernel().upper()}",
f"Python Version: {_version}",
f"User: {_get_login()}",
f"`frpc` Available: {_frpc_exists()}",
f"Module Path: {MODULE_PATH}",
f"LEADS Version: {leads_version}",
f"LEADS VeC Version: {__version__}",
sep="\n")
else:
if args.action == "replay":
args.devices = f"{MODULE_PATH}/replay.py"
args.emu = False
_L.debug("Replay mode enabled")
_exit(run(parse_path(args.config), parse_path(args.devices), parse_path(args.main), args.register,
parse_path(args.theme), args.magnify_font_sizes, args.emu, args.auto_mfs, args.ignore_import_error))
_exit()
1 change: 1 addition & 0 deletions leads_vec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
raise ImportError("Please install `pynput` to run this module\n>>>pip install pynput")

from leads_vec.run import *
from leads_vec.__entry__ import __entry__
62 changes: 2 additions & 60 deletions leads_vec/__main__.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,5 @@
from argparse import ArgumentParser as _ArgumentParser, BooleanOptionalAction as _BooleanOptionalAction
from importlib.metadata import version as _package_version, PackageNotFoundError as _PackageNotFoundError
from os import getlogin as _get_login
from os.path import abspath as _abspath
from sys import exit as _exit, version as _version
from warnings import filterwarnings as _filterwarnings

from leads import L as _L
from leads_gui.system import get_system_kernel as _get_system_kernel
from leads_vec.run import run


def parse_path(path: str | None) -> str | None:
return path.replace(":INTERNAL", MODULE_PATH) if path else None
from leads_vec.__entry__ import __entry__


if __name__ == "__main__":
_filterwarnings("ignore")
MODULE_PATH = _abspath(__file__)[:-12]

parser = _ArgumentParser(prog="LEADS VeC", description="Lightweight Embedded Assisted Driving System VeC",
epilog="ProjectNeura: https://projectneura.org\n"
"GitHub: https://github.com/ProjectNeura/LEADS")
parser.add_argument("action", choices=("info", "replay", "run"))
parser.add_argument("-c", "--config", default=None, help="specify a configuration file")
parser.add_argument("-d", "--devices", default=f"{MODULE_PATH}/devices.py", help="specify a devices module")
parser.add_argument("-m", "--main", default=f"{MODULE_PATH}/cli.py", help="specify a main module")
parser.add_argument("-r", "--register", choices=("systemd", "config", "reverse_proxy"), default=None,
help="register a service")
parser.add_argument("-t", "--theme", default=None, help="specify a theme")
parser.add_argument("-mfs", "--magnify-font-sizes", type=float, default=1, help="magnify font sizes by a factor")
parser.add_argument("--emu", action=_BooleanOptionalAction, default=False, help="use emulator")
parser.add_argument("--auto-mfs", action=_BooleanOptionalAction, default=False,
help="automatically magnify font sizes to match the original proportion")
parser.add_argument("--ignore-import-error", action=_BooleanOptionalAction, default=False,
help="ignore `ImportError`")
args = parser.parse_args()
if args.action == "info":
from leads_vec.__version__ import __version__
from ._bootloader import frpc_exists as _frpc_exists

leads_version = "Unknown"
try:
leads_version = _package_version("leads")
except _PackageNotFoundError:
_L.warn("Failed to retrieve package version (did you install through pip?)")
_L.info(f"LEADS VeC",
f"System Kernel: {_get_system_kernel().upper()}",
f"Python Version: {_version}",
f"User: {_get_login()}",
f"`frpc` Available: {_frpc_exists()}",
f"Module Path: {MODULE_PATH}",
f"LEADS Version: {leads_version}",
f"LEADS VeC Version: {__version__}",
sep="\n")
else:
if args.action == "replay":
args.devices = f"{MODULE_PATH}/replay.py"
args.emu = False
_L.debug("Replay mode enabled")
_exit(run(parse_path(args.config), parse_path(args.devices), parse_path(args.main), args.register,
parse_path(args.theme), args.magnify_font_sizes, args.emu, args.auto_mfs, args.ignore_import_error))
_exit()
__entry__()
19 changes: 19 additions & 0 deletions leads_vec_rc/__entry__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from argparse import ArgumentParser as _ArgumentParser

from uvicorn import run as _run

from leads import register_config as _register_config, load_config as _load_config
from leads_gui import Config as _Config


def __entry__() -> None:
parser = _ArgumentParser(prog="LEADS VeC RC",
description="Lightweight Embedded Assisted Driving System VeC Remote Controller",
epilog="GitHub: https://github.com/ProjectNeura/LEADS")
parser.add_argument("-c", "--config", default=None, help="specify a configuration file")
parser.add_argument("-p", "--port", type=int, default=8000, help="specify a server port")
args = parser.parse_args()
_register_config(_load_config(args.config, _Config) if args.config else _Config({}))
from leads_vec_rc.cli import app

_run(app, host="0.0.0.0", port=args.port, log_level="warning")
Loading