mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-04-26 10:58:04 +00:00
Remove the schedule package; align fixed alarm times with bot timezone via get_config_timezone like MessageScheduler.
186 lines
6.2 KiB
TOML
186 lines
6.2 KiB
TOML
# pyproject.toml
|
|
[build-system]
|
|
requires = ["setuptools>=61.0", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "meshcore-bot"
|
|
version = "0.1.0"
|
|
description = "MeshCore Bot using the meshcore-cli and meshcore.py packages"
|
|
readme = "README.md"
|
|
requires-python = ">=3.9"
|
|
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.2.31",
|
|
"openmeteo-requests>=1.7.2",
|
|
"requests-cache>=1.1.1",
|
|
"retry-requests>=1.0.0",
|
|
"flask>=2.3.0",
|
|
"flask-socketio>=5.3.0",
|
|
"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 = "modules.web_viewer.app:main"
|
|
|
|
[tool.setuptools]
|
|
# Include both the main module and the modules package
|
|
py-modules = ["meshcore_bot"]
|
|
packages = ["modules", "modules.commands", "modules.commands.alternatives",
|
|
"modules.commands.alternatives.inactive", "modules.service_plugins", "modules.web_viewer"]
|
|
|
|
[tool.setuptools.package-data]
|
|
"*" = ["*.json"]
|
|
modules = [
|
|
"web_viewer/templates/*.html",
|
|
"web_viewer/static/*",
|
|
"web_viewer/static/*/*",
|
|
"web_viewer/static/*/*/*",
|
|
]
|
|
|
|
[tool.ruff]
|
|
line-length = 120
|
|
target-version = "py39"
|
|
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
|
|
# 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.utils",
|
|
"modules.plugin_loader",
|
|
"modules.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",
|
|
"modules.web_viewer.app",
|
|
"modules.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
|