mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-06-03 22:31:18 +00:00
003ffb598c
Added gevent and gevent-websocket as dependencies to improve performance and compatibility. Updated the web viewer launch process to utilize subprocess instead of multiprocessing for better management. Adjusted the method for checking the viewer process status to use polling, ensuring accurate process state handling. Refactored the meshcore-viewer script entry point for consistency.
196 lines
6.6 KiB
TOML
196 lines
6.6 KiB
TOML
# pyproject.toml
|
|
[build-system]
|
|
requires = ["setuptools>=61.0", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "meshcore-bot"
|
|
version = "0.9.2"
|
|
description = "MeshCore Bot with commands for mesh testing, utilities, and service integration."
|
|
readme = "README.md"
|
|
requires-python = ">=3.10"
|
|
dependencies = [
|
|
"pyserial>=3.5",
|
|
"bleak>=0.20.0",
|
|
"asyncio-mqtt>=0.11.0",
|
|
"configparser>=5.3.0",
|
|
"python-dateutil>=2.8.2",
|
|
"apscheduler>=3.10.0",
|
|
"colorlog>=6.7.0",
|
|
"requests>=2.31.0",
|
|
"urllib3>=2.0.0",
|
|
"pyephem>=4.1.4",
|
|
"geopy>=2.3.0",
|
|
"maidenhead>=1.4.0",
|
|
"pytz>=2023.3",
|
|
"aiohttp>=3.8.0",
|
|
"meshcore>=2.3.6",
|
|
"openmeteo-requests>=1.7.2",
|
|
"requests-cache>=1.1.1",
|
|
"retry-requests>=1.0.0",
|
|
"flask>=2.3.0",
|
|
"flask-socketio>=5.3.0",
|
|
"gevent>=24.2.1",
|
|
"gevent-websocket>=0.10.1",
|
|
"meshcore-cli",
|
|
"feedparser>=6.0.10",
|
|
"paho-mqtt>=1.6.0",
|
|
"cryptography>=41.0.0",
|
|
"pynacl>=1.5.0",
|
|
"aiosqlite>=0.19.0",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
profanity = ["better-profanity>=0.7.0", "unidecode>=1.3.0"]
|
|
geo = ["pycountry>=23.12.0", "us>=2.0.0"]
|
|
test = ["pytest>=7.0", "pytest-asyncio>=0.21", "pytest-mock>=3.10", "pytest-cov>=4.0", "pytest-timeout>=2.1.0", "types-requests>=2.31"]
|
|
docs = ["mkdocs-material>=9.0.0", "mkdocs-exclude>=1.0.0"]
|
|
|
|
[project.scripts]
|
|
meshcore-bot = "meshcore_bot:main"
|
|
meshcore-viewer = "web_viewer._launcher:_main"
|
|
|
|
[tool.setuptools]
|
|
# Include both the main module and the modules package
|
|
py-modules = ["meshcore_bot"]
|
|
packages = ["shared", "shared.parsers",
|
|
"modules", "modules.commands", "modules.commands.alternatives",
|
|
"modules.commands.alternatives.inactive", "modules.service_plugins",
|
|
"web_viewer"]
|
|
|
|
[tool.setuptools.package-data]
|
|
"*" = ["*.json"]
|
|
web_viewer = [
|
|
"templates/*.html",
|
|
"static/*",
|
|
"static/*/*",
|
|
"static/*/*/*",
|
|
]
|
|
|
|
[tool.ruff]
|
|
line-length = 120
|
|
target-version = "py310"
|
|
exclude = [".venv", "build", "dist"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "W", "I", "UP", "B", "C4", "SIM"]
|
|
ignore = [
|
|
"E501", # line too long (handled by formatter)
|
|
# Legacy-code tolerances — pervasive in pre-typed source, not worth a bulk churn:
|
|
"E701", # multiple-statements-on-one-line-colon
|
|
"E702", # multiple-statements-on-one-line-semicolon
|
|
"E711", # comparison-to-none (== None common in legacy)
|
|
"E712", # comparison-to-true (== True/False common in legacy)
|
|
"E722", # bare-except (used extensively in graceful-degradation patterns)
|
|
"E741", # ambiguous-variable-name (l, O, I in legacy loops)
|
|
"E402", # module-level import not at top (conditional imports pattern)
|
|
"F601", # multi-value-repeated-key-literal (legacy dict pattern)
|
|
"B007", # unused-loop-control-variable (rename to _ is a bulk churn)
|
|
"B023", # function-uses-loop-variable (legacy closures in packet capture)
|
|
"B904", # raise-without-from-in-except (legacy raise pattern)
|
|
"C408", # unnecessary-collection-call
|
|
"C414", # unnecessary-double-cast-or-process
|
|
# pyupgrade rules that would require a bulk typing rewrite — deferred to a code-quality PR:
|
|
"UP007", # non-pep604-annotation-union (Union[X, Y] -> X | Y)
|
|
"UP035", # deprecated-import (typing.List/Dict/... remain prevalent)
|
|
"UP041", # timeout-error-alias (socket.timeout -> TimeoutError)
|
|
"UP045", # non-pep604-annotation-optional (Optional[X] -> X | None)
|
|
# Simplification suggestions — stylistic, not enforced on legacy code:
|
|
"SIM102", # collapsible-if
|
|
"SIM103", # needless-bool
|
|
"SIM105", # suppressible-exception
|
|
"SIM108", # if-else-block-instead-of-if-exp (ternary preference is subjective)
|
|
"SIM109", # compare-with-tuple
|
|
"SIM110", # reimplemented-builtin
|
|
"SIM114", # if-with-same-arms
|
|
"SIM115", # open-file-with-context-handler
|
|
"SIM117", # multiple-with-statements
|
|
"SIM210", # if-expr-with-true-false
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"tests/*" = ["S101"]
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# mypy — incremental strict mode
|
|
# ---------------------------------------------------------------------------
|
|
# Global baseline: safe non-breaking options.
|
|
# Per-module overrides below tighten settings for fully-typed modules.
|
|
[tool.mypy]
|
|
python_version = "3.11"
|
|
ignore_missing_imports = true
|
|
warn_unused_ignores = true
|
|
warn_return_any = false # too noisy until all modules are annotated
|
|
warn_unused_configs = true
|
|
no_implicit_optional = true
|
|
strict_optional = true
|
|
|
|
# New modules written with full type annotations get strict treatment.
|
|
[[tool.mypy.overrides]]
|
|
module = [
|
|
"modules.commands.schedule_command",
|
|
"modules.service_plugins.webhook_service",
|
|
"modules.service_plugins.base_service",
|
|
"modules.message_handler",
|
|
"modules.utils",
|
|
"modules.plugin_loader",
|
|
"shared.security_utils",
|
|
"modules.commands.base_command",
|
|
]
|
|
disallow_untyped_defs = true
|
|
disallow_incomplete_defs = true
|
|
check_untyped_defs = true
|
|
no_implicit_optional = true
|
|
|
|
# Modules with known type errors not yet brought up to strict standard.
|
|
# Suppress all mypy errors for these modules until they are fully annotated.
|
|
[[tool.mypy.overrides]]
|
|
module = [
|
|
"modules.core",
|
|
"modules.command_manager",
|
|
"modules.feed_manager",
|
|
"modules.mesh_graph",
|
|
"modules.scheduler",
|
|
"modules.maintenance",
|
|
"modules.transmission_tracker",
|
|
"modules.commands.alert_command",
|
|
"modules.commands.announcements_command",
|
|
"modules.commands.aurora_command",
|
|
"modules.commands.channels_command",
|
|
"modules.commands.greeter_command",
|
|
"modules.commands.help_command",
|
|
"modules.commands.joke_command",
|
|
"modules.commands.multitest_command",
|
|
"modules.commands.prefix_command",
|
|
"modules.commands.wx_command",
|
|
"modules.commands.alternatives.wx_international",
|
|
"modules.commands.trace_command",
|
|
"modules.commands.solarforecast_command",
|
|
"modules.commands.roll_command",
|
|
"modules.commands.repeater_command",
|
|
"modules.commands.path_command",
|
|
"modules.commands.sports_command",
|
|
"modules.commands.aqi_command",
|
|
"modules.service_plugins.discord_bridge_service",
|
|
"modules.service_plugins.packet_capture_service",
|
|
"modules.service_plugins.weather_service",
|
|
"web_viewer.app",
|
|
"web_viewer.integration",
|
|
]
|
|
ignore_errors = true
|
|
|
|
[tool.pytest.ini_options]
|
|
# Hard limit every test to 30 s; prevents hangs from blocking I/O or infinite loops.
|
|
# Individual tests that legitimately need longer can use @pytest.mark.timeout(N).
|
|
timeout = 30
|
|
timeout_method = "thread"
|
|
asyncio_mode = "auto"
|
|
|
|
[tool.coverage.run]
|
|
source = ["modules"]
|
|
omit = ["tests/*", ".venv/*"]
|
|
|
|
[tool.coverage.report]
|
|
fail_under = 35
|
|
show_missing = true
|