Commit Graph

523 Commits

Author SHA1 Message Date
agessaman 003ffb598c refactor(web_viewer): update web viewer integration and dependencies
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.
2026-05-18 22:07:06 -07:00
agessaman 1e6da4a08c refactor(web_viewer): improve web viewer process management and logging
Updated the web viewer integration to utilize multiprocessing for running the viewer process, enhancing process management. Adjusted the logging configuration for better clarity and consistency. Removed deprecated timeout configurations and streamlined the shutdown process for the web viewer, ensuring graceful termination and improved error handling.
2026-05-18 21:41:26 -07:00
agessaman 8a65f48028 refactor(web_viewer): move modules/web_viewer/ to top-level web_viewer/
Physically separates the web viewer from the bot package. Entry point
updated to web_viewer.app:main, pyproject.toml packages/package-data
updated accordingly. Fixed bot_root path calculation (was ../../ from
modules/web_viewer, now ../ from web_viewer). All 2866 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:13:13 -07:00
agessaman c69a3af4e6 refactor(core): extract admin server and default config from core.py
Moves _BotAdminServer to modules/admin_server.py (renamed BotAdminServer)
and the create_default_config method + 360-line template string to
modules/default_config.py. core.py shrinks from 2,289 to ~1,870 lines;
all 44 core tests and 2866 total tests still pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:06:28 -07:00
agessaman 8f04d8ceb6 refactor(shared): create shared/parsers/ for path and packet parsing
Extracts canonical path-parsing and packet-hashing logic from
modules/utils.py into shared/parsers/path_parser.py and
shared/parsers/packet_parser.py, eliminating duplication across
three prior implementations. All callers updated to import from
shared.parsers.*; modules/utils.py re-exports via shared imports
for any remaining internal callers. 2866 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:50:59 -07:00
agessaman 7042059d6d refactor(shared): extract geocoding and text utilities into shared/
Move geocoding functions (calculate_distance, Nominatim wrappers, geocode_city/zipcode,
location normalization) from modules/utils.py to shared/geocoding.py.

Move text formatting functions (abbreviate_location, truncate_string,
decode_escape_sequences, format_location_for_display, format_elapsed_display)
to shared/text_utils.py.

utils.py shrinks from 2,447 to ~1,125 lines. Update imports across ~25 files.
No logic changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 17:36:11 -07:00
agessaman 23da88c37d refactor(shared): create shared/ package and migrate foundation modules
Move models.py, db_manager.py, db_migrations.py, and security_utils.py
from modules/ to a new shared/ top-level package that can be imported by
both the bot and the web viewer without coupling them.

Update all imports across ~75 files (commands, service plugins, tests,
web viewer, generate_website.py). No logic changes — pure file moves and
import path updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 17:19:46 -07:00
agessaman 0b56e86de9 feat(multibyte): add multibyte monitor feature with API endpoints
- Introduced a new configuration option `multibyte_monitor_enabled` in `config.ini.example` to control the visibility of the multibyte monitor page and API endpoints.
- Implemented the `/multibyte-rollout` and `/api/multibyte-rollout` routes in the web viewer, which are accessible only when the multibyte monitor feature is enabled.
- Updated documentation in `web-viewer.md` to reflect the new feature and its configuration.
- Added tests to ensure the multibyte routes are disabled by default and accessible when enabled.
2026-05-18 16:39:48 -07:00
agessaman 33f50a9fdc chore(docs): update documentation URL and bump version to 0.9.2
- Changed the documentation URL in the meshcore-bot.service file to point to the correct repository.
- Updated the project version in pyproject.toml from 0.9.1 to 0.9.2 for consistency in versioning.
- Modified the User-Agent string in dadjoke_command.py to reflect the new repository URL.
2026-05-17 14:42:05 -07:00
agessaman cb54ca6a45 fix(config): clarify flood scope configuration and logging behavior
- Updated `config.ini.example` and `configuration.md` to enhance clarity on the `outgoing_flood_scope_override` and `flood_scopes` settings, detailing their behavior and interactions.
- Improved logging in `CommandManager` to provide better insights into scope resolution and potential issues during message sending.
- Added new methods in `MessageHandler` for improved RF data correlation, ensuring eligibility checks for flood scope matching.
- Enhanced unit tests to cover new behaviors and ensure robust handling of flood scope configurations.
2026-05-17 14:38:47 -07:00
agessaman 41fe46babb refactor(packet_capture_service): enhance logging configuration and per-packet summary
- Removed global logger level setting and introduced a method to apply log levels based on service-specific verbose/debug settings.
- Added a new method for logging per-packet summaries, allowing for more granular logging control based on verbosity and debug flags.
- Updated packet logging to utilize the new summary method, ensuring appropriate log levels are used for packet capture actions.
2026-05-17 11:28:41 -07:00
agessaman 4205780492 fix(webhook): normalize # prefix in channel name lookup
Strip leading # when resolving channel names so webhook posts match
hashtag channels cached from the radio. Return HTTP 500 when mesh send
returns false instead of reporting success.
2026-05-16 19:35:37 -07:00
agessaman 0defa29e43 fix(webhook_service): streamline mesh scope assignment
Updated the mesh scope assignment logic in the WebhookService to use a more concise inline conditional expression. This change improves code readability while maintaining the same functionality for determining the appropriate mesh scope based on the incoming request body.
2026-05-16 12:18:14 -07:00
agessaman 3632794f58 fix(darc_mowas_service): assign ascending timestamps to chunks in send_chunks method
Updated the _send_chunks method to assign timestamps based on the chunk index, ensuring each chunk receives a unique timestamp that increments by one second. This change facilitates proper ordering and deduplication of messages on the client side. Added a unit test to verify the correct behavior of timestamp assignment during chunk transmission.
2026-05-16 12:13:23 -07:00
agessaman 61ee86168b chore(workflows): exclude dist directory from shellcheck
Updated the GitHub Actions workflow to exclude the dist directory from shellcheck checks, ensuring cleaner linting results.

fix(command_manager): reorder datetime import

Moved the datetime import to the correct position in command_manager.py for better code organization.

fix(reload_config): improve config value retrieval

Refactored the _read_config_value function in reload_config.sh to ensure default values are returned correctly when the key is not found in the config file.

fix(tests): adjust imports in test_scheduler_logic

Updated import statements in test_scheduler_logic.py for consistency and clarity.
2026-05-16 12:11:51 -07:00
agessaman 74b7de6f72 feat(flood_scope): enhance flood scope handling across services
- Introduced optional regional TC_FLOOD scope configuration for various services, allowing for more granular control over message routing.
- Updated the CommandManager to resolve and apply flood scopes from messages, configuration sections, and explicit parameters, ensuring correct message delivery.
- Enhanced service plugins to utilize the new flood scope functionality, including weather, earthquake, and webhook services.
- Added unit tests to verify the correct resolution and application of flood scopes in different scenarios, ensuring robust functionality.
2026-05-16 12:08:24 -07:00
agessaman d038402875 fix(CommandManager): use sender_pubkey for DM responses to prevent misrouting
Updated the CommandManager to prioritize sender_pubkey over sender_id when sending direct messages. This change ensures correct routing of messages, especially in cases where multiple nodes share similar display names. Added tests to verify the new behavior and ensure proper functionality.
2026-05-16 10:08:18 -07:00
Adam Gessaman 8370c9ddcc Merge pull request #182 from fmoessbauer/fm/improve-service-name
chore(base_service): strip underscores in service name
2026-05-16 08:35:34 -07:00
Felix Moessbauer 48b3f4e6bd feat(darc_mowas_service): Re-transmit bit identical messages
For the emergency communication, we need to ensure that all messages are
transmitted (and received) correctly. We already check if a repeater
acks our message, however a missing ack does not tell us if the message
was lost, or the ack. For that, we repeat the message in this case,
leading to potentially content-wise duplicated receptions on the network.

To let the network depulicate the traffic, the re-transmissions need to
be bit identical with the original message. For that, we compute a
timestamp on initial send and use the same timestamp on
re-transmissions (per message). This further allows clients to
chronologically sort the received messages, making the result easier to
read.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-05-16 16:19:22 +02:00
Felix Moessbauer db8a519b95 feat(CommandManager): Allow to pass timestamp on send_channel_message
By that, bit identical replications of channel messages can be created,
which is needed if re-transmissions are performed that should be
deduplicated by the receiver. It further is possible (if the client
supports this) to control the display order of the messages
(chronological).

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-05-16 16:19:03 +02:00
Felix Moessbauer 854c04d950 chore(base_service): strip underscores in service name
Some services are named <foo>_Service, whereby currently only the
Service part is stripped. By that, the service name is derived to be
<foo>_, instead of <foo>.

We fix this by stripping all leading and trailing underscores in the
service name.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-05-16 15:27:35 +02:00
agessaman 9d24e4824c feat(config, docs): add JWT configuration options for MQTT authentication
- Introduced `jwt_ttl_seconds` and `jwt_renewal_interval` settings in `config.ini.example` for global JWT management, allowing for better control over token expiration and renewal intervals.
- Updated documentation in `packet-capture.md` to clarify the usage of global and per-broker JWT settings, enhancing user understanding of authentication configurations.
- Refactored `PacketCaptureService` to incorporate new JWT settings, ensuring consistent handling of token lifetimes and renewal processes.
2026-05-15 20:46:05 -07:00
agessaman c91baf1fdf refactor(message_handler, repeater_manager): enhance contact advertisement tracking
- Updated the `track_contact_advertisement` method to return a structured result indicating success and duplicate packet status, improving clarity in handling contact advertisements.
- Adjusted the `MessageHandler` to utilize the new result structure, allowing for better decision-making based on tracking outcomes.
- Enhanced unit tests to cover new behaviors and ensure correct handling of duplicate packets and advertisement tracking results.
2026-05-15 20:03:04 -07:00
agessaman 4a0b989f5a feat(scheduler): optional flood scope for scheduled channel messages
Parse channel:#scope:body in [Scheduled_Messages], pass scope to
send_channel_message; extend schedule list and docs.
2026-05-14 11:32:20 -07:00
agessaman d4eba9ad11 fix(scheduler): stagger scheduled sends and skip global rate limit
Scheduled cron jobs now pass the cron key into the send path, apply a
deterministic [0, N) second delay from scheduled_message_max_stagger_seconds
(default 1.5), and call send_channel_message with skip_user_rate_limit=True
so simultaneous jobs are not dropped by rate_limit_seconds. Per-channel and
bot_tx limits still apply. Document the new Bot key in config.ini.example;
tests assert kwargs, skip flag, and stagger behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 11:18:25 -07:00
agessaman bcd61fe805 fix(mesh_graph): optimize pending updates flushing logic to prevent deadlock
- Simplified the flushing mechanism for pending updates in the MeshGraph class by introducing a `flush_needed` flag to reduce redundant calls to `_flush_pending_updates_sync()`.
2026-05-13 07:54:09 -07:00
agessaman 39e6128778 fix(feed_manager, scheduler): improve message processing and concurrency handling
- Enhanced the FeedManager to prevent coroutine pileup by checking the lock status before acquiring it, allowing for more efficient message processing.
- Introduced a persistent dictionary to track the last send time for each feed, ensuring send intervals are respected without blocking.
- Updated the MessageScheduler to fire-and-forget the message processing, improving responsiveness and logging errors without blocking the main thread.
2026-05-12 19:38:47 -07:00
agessaman 70b2256752 feat(test): Test_Command response_format with piped path filters
Add format_piped_template (pathbytes_min, prefix_if_nonempty), utils
bytes-per-hop helpers, and [Test_Command] format priority over Keywords.
2026-05-12 19:30:42 -07:00
agessaman 13f22e4d7b feat(path_command): add reply prefix and minimum path bytes configuration
- Introduced `reply_prefix` to prepend a customizable string to path command replies, supporting placeholders for dynamic content.
- Added `minimum_path_bytes` setting to control the resolution of repeater names based on the number of bytes per hop, enhancing path command behavior.
- Updated relevant documentation and translations to reflect these new configuration options.
- Implemented unit tests to ensure correct functionality of the new features.
2026-05-12 17:23:22 -07:00
agessaman 5879838d8b feat(command_manager): Fix flood scope on keyword and RandomLine channel replies
Route process_message keyword/RandomLine sends through send_response so
reply_scope reaches set_flood_scope; add optional command_id to
send_response for transmission tracking.
2026-05-10 19:20:22 -07:00
agessaman 4d35e103a2 refactor(scheduler): enhance scheduled message configuration and parsing
- Updated the scheduled message format in `config.ini.example` to support 5-field cron expressions and preset aliases, replacing the deprecated HHMM format.
- Improved the `MessageScheduler` class to parse and validate new schedule formats, logging warnings for deprecated usage.
- Adjusted the `ScheduleCommand` to display scheduled messages with their respective cron or preset labels.
- Added unit tests to ensure correct parsing and handling of various schedule formats, including legacy HHMM and cron expressions.
2026-05-05 14:12:02 -07:00
agessaman 6d496934d9 refactor(advert_parsing): improve flag handling in message and map uploader services
- Replaced the use of AdvertFlags enum for flag parsing with bitwise operations to handle invalid values correctly.
- Updated the parsing logic in both MessageHandler and MapUploaderService to use boolean flags for better clarity and performance.
- Adjusted error logging to use warnings instead of errors for parsing issues, enhancing the logging strategy.
- Added unit tests to ensure correct parsing behavior for edge cases with invalid flag values.
2026-05-04 15:45:38 -07:00
agessaman dfa5dc2e01 feat(services): add Discord/Telegram outbound helpers and repeater discovery alerts
Add bridge_outbound posting, BaseServicePlugin.send_external_notifications,
and RepeaterPrefixCollision discovery vs collision routing with silence_mesh_output.
2026-05-02 21:50:03 -07:00
agessaman 2183f8e246 refactor(message_handler): standardize string quotes and improve code readability
- Updated string quotes from single to double quotes for consistency across the MessageHandler class.
- Enhanced formatting of method parameters for better readability.
- Minor adjustments to logging statements for clarity.
2026-05-01 21:32:54 -07:00
agessaman 263c73c2e2 feat(packet_capture): enhance MQTT packet publishing controls and path length decoding
- Added configuration options `mqtt_skip_unparseable_packets` and `advert_require_valid_signature` to control MQTT publishing behavior based on packet validity.
- Updated `decode_path_len_byte` function to return `None` for reserved size codes, improving path length validation.
- Implemented logic in `PacketCaptureService` to skip publishing unparseable packets and ADVERT packets with invalid signatures.
- Introduced `verify_meshcore_advert_ed25519` function for signature verification of ADVERT packets, with corresponding unit tests to ensure functionality.
- Enhanced documentation to reflect new configuration options and their effects on packet processing.
2026-05-01 21:32:40 -07:00
agessaman 5a484d1db2 feat(web_viewer): add channel_name validation and update feed functionality
- Implemented validation for the `channel_name` field to ensure it is not empty when updating feeds, raising a ValueError if validation fails.
- Added test cases to verify that updates to `channel_name` persist correctly and that attempts to set an empty `channel_name` are rejected with an appropriate error response.
2026-04-25 21:34:17 -07:00
agessaman d000e9858e fix(repeater_manager): update purging log insertion to include public_key and name
- Modified the SQL insert statement in the RepeaterManager class to include `public_key` and `name` fields, ensuring compatibility with the new schema.
- Updated corresponding test cases to reflect changes in the database operation, maintaining the integrity of the purging log functionality.
2026-04-25 21:25:43 -07:00
agessaman d34ad24e9b feat(weather): add default city configuration for wx commands
- Introduced a new configuration option `default_city` in `config.ini.example` for fallback city names when no location is provided.
- Updated `wx_command.py` and `wx_international.py` to utilize the `default_city` for location disambiguation, enhancing user experience when companion location is unavailable.
- Improved logging to reflect the use of default city or bot location as fallback options.
2026-04-25 21:15:51 -07:00
agessaman ad4de524f8 merge(dev): resolve scheduler conflict in PR #163
Merge latest dev into the PR branch and keep both DateTrigger and EventType imports so scheduler changes remain compatible and conflict-free.

Made-with: Cursor
2026-04-25 21:03:36 -07:00
agessaman bcb3f48f02 fix(web_viewer): restore mesh export and clean scheduler imports
Prevent exportView runtime failure by restoring the download anchor setup and move radio param imports to module scope so Ruff passes on the PR changes.

Made-with: Cursor
2026-04-25 21:01:14 -07:00
agessaman 0f3ecea42e refactor(darc_mowas_service): improve imports and type hints
- Replaced direct imports of `pytz` with dynamic imports for better compatibility.
- Updated type hints for server and loop attributes in the DARC MoWaS service.
- Enhanced XML handling by specifying `xml.dom.minidom.Element` in method signatures.
- Improved message processing logic to handle missing channels and ensure valid area descriptions.
- Refactored `_child_text` function to accept both `Document` and `Element` types for better flexibility.
- Adjusted unit tests to reflect changes in the DARC MoWaS service structure.
2026-04-25 20:37:47 -07:00
Adam Gessaman a5f3cb008a Merge pull request #165 from fmoessbauer/fm/darc-mowas-api
feat: add implementation of the DARC MoWaS gateway
2026-04-25 20:29:34 -07:00
agessaman 6d80ad03da feat(trace_command): enhance path parsing for multibyte nodes and update documentation
- Updated the TraceCommand class to support parsing of 1-byte, 2-byte, and 3-byte hex node paths.
- Improved the _extract_path_from_message and _parse_path_arg methods to handle multibyte node formats and enforce consistent length checks.
- Enhanced help text and usage examples to reflect new path formats.
- Added unit tests for multibyte path parsing and reciprocal path building to ensure correct functionality.
2026-04-25 20:28:41 -07:00
agessaman 2e7c56207a fix(message_handler): improve public key retrieval logic
- Updated the logic for retrieving the sender's public key in the MessageHandler class to ensure it defaults to sender_id when pubkey_prefix is not available.
- Enhanced the condition to check for sender_id presence before accessing contacts, improving robustness in public key resolution.
2026-04-25 19:59:16 -07:00
agessaman 63592bdd65 feat(commands, config): implement path byte length requirements for commands
- Added configuration options to specify minimum path byte length requirements for the path, test, and multitest commands.
- Introduced methods to enforce these requirements and handle failure responses.
- Updated the packet capture service to correctly calculate packet hashes using the raw wire byte length.
- Enhanced unit tests to verify the correct behavior of the new path byte length logic.
2026-04-25 09:05:17 -07:00
Felix Moessbauer 63fcd26f7c feat(darc_mowas_service): retry messages that are not acked
For alert messages it is imporant to be sure they are received by the
network. For that, we implement a retry logic that waits for at least
one ack from a repeater and re-sends the message chunk if non is
received within a retry timeout.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:44 +02:00
Felix Moessbauer ffd93edd96 feat: add implementation of the DARC MoWaS gateway
We implement support for the DARC MoWaS service that distributes
emergency messages from the German BBK via the "Warnmultiplikator"
interface to Meshcore channels. This service is push-based and receives
alerts on /api/alert, which are then formatted similar to cell-broadcast
messages (without modification of the text) and re-distributed on
Meshcore.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:43 +02:00
agessaman 5f40c45f07 feat(PacketCapture): align RX/RAW correlation with meshcore-packet-capture
Deduplicate RAW_DATA against RX_LOG_DATA hex, cache RF metadata by packet
prefix, extend RAW payload extraction, fix payload_len for multi-byte paths.
2026-04-21 19:26:09 -07:00
agessaman 23cdce03e8 feat(db_migrations, message_handler, repeater_manager): enhance purging log functionality
- Added a new migration to include a 'details' column in the 'purging_log' table for improved logging of actions.
- Refactored the `log_purging_action` method in `RepeaterManager` to handle both new and legacy schemas, ensuring compatibility with the updated database structure.
- Updated `MessageHandler` to utilize the new logging method, replacing direct database updates with a unified logging approach.
- Added tests to verify the presence of the new column and the correct functionality of the logging mechanism across different scenarios.
2026-04-21 17:04:51 -07:00
agessaman 8e71a11bd1 feat(command_manager): enhance DM recipient resolution with public key prefix lookup
- Updated `send_dm` method to first attempt contact resolution by name, and if that fails, fallback to resolving by public key prefix.
- Improved logging to indicate the method of recipient resolution used.
- Added tests to verify the new recipient resolution logic, ensuring correct behavior when looking up contacts by public key prefix and handling failures appropriately.
2026-04-21 10:07:40 -07:00