mmrelay 1.2.1__py3-none-any.whl → 1.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mmrelay might be problematic. Click here for more details.

@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- Description=A Meshtastic <=> Matrix Relay
2
+ Description=MMRelay - Meshtastic <=> Matrix Relay
3
3
  After=network-online.target
4
4
  Wants=network-online.target
5
5
 
@@ -11,6 +11,7 @@ WorkingDirectory=%h/.mmrelay
11
11
  Restart=on-failure
12
12
  RestartSec=10
13
13
  Environment=PYTHONUNBUFFERED=1
14
+ Environment=LANG=C.UTF-8
14
15
  # Ensure both pipx and pip environments are properly loaded
15
16
  Environment=PATH=%h/.local/bin:%h/.local/pipx/venvs/mmrelay/bin:/usr/local/bin:/usr/bin:/bin
16
17
 
@@ -3,78 +3,17 @@ services:
3
3
  image: ghcr.io/jeremiah-k/mmrelay:latest
4
4
  container_name: meshtastic-matrix-relay
5
5
  restart: unless-stopped
6
+ stop_grace_period: 30s
6
7
  user: "${UID:-1000}:${GID:-1000}"
7
-
8
8
  environment:
9
- - TZ=UTC
10
- - PYTHONUNBUFFERED=1
11
- - MPLCONFIGDIR=/tmp/matplotlib
12
-
13
- # Matrix Authentication: Use 'mmrelay auth login' on host system to create credentials.json
14
- # The credentials file will be automatically loaded from the volume mount below
15
-
16
- # Meshtastic Connection Settings - Uncomment and configure as needed
17
- # TCP Connection (most common)
18
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=tcp
19
- # - MMRELAY_MESHTASTIC_HOST=192.168.1.100
20
- # - MMRELAY_MESHTASTIC_PORT=4403 # Default port
21
-
22
- # Serial Connection (uncomment for serial)
23
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=serial
24
- # - MMRELAY_MESHTASTIC_SERIAL_PORT=/dev/ttyUSB0
25
-
26
- # BLE Connection (uncomment for Bluetooth)
27
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=ble
28
- # - MMRELAY_MESHTASTIC_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
29
-
30
- # Meshtastic Operational Settings
31
- # - MMRELAY_MESHTASTIC_BROADCAST_ENABLED=true
32
- # - MMRELAY_MESHTASTIC_MESHNET_NAME=My Mesh Network
33
- # - MMRELAY_MESHTASTIC_MESSAGE_DELAY=2.2 # Minimum 2.0 seconds
34
-
35
- # System Configuration
36
- # - MMRELAY_LOGGING_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
37
- # - MMRELAY_LOG_FILE=/app/data/logs/mmrelay.log # Enables file logging
38
- # - MMRELAY_DATABASE_PATH=/app/data/meshtastic.sqlite
39
-
40
- # Note: Environment variables for Meshtastic, logging, and database settings take precedence over config.yaml
41
-
9
+ - TZ=UTC # Set timezone (PYTHONUNBUFFERED and MPLCONFIGDIR are set in Dockerfile)
42
10
  volumes:
43
- # Map entire ~/.mmrelay directory to /app/data to maintain proper structure
44
- # This includes config.yaml, plugins/, data/, logs/, credentials.json, and any other subdirectories
45
- # The --data-dir parameter in CMD points to /app/data
46
- # Create config.yaml first - see docs/DOCKER.md for setup instructions
47
- - ${MMRELAY_HOME}/.mmrelay:/app/data
48
-
49
- # For TCP connections (most common) - Meshtastic typically uses port 4403
50
- ports:
51
- - 4403:4403
52
-
53
- # For serial connections, uncomment the device you need:
54
- # devices:
55
- # - /dev/ttyUSB0:/dev/ttyUSB0
56
- # - /dev/ttyACM0:/dev/ttyACM0
57
-
58
- # For BLE connections, uncomment these:
59
- # privileged: true
60
- # network_mode: host
61
- # Additional volumes for BLE (add to existing volumes section above):
62
- # - /var/run/dbus:/var/run/dbus:ro
63
- # - /sys/bus/usb:/sys/bus/usb:ro
64
- # - /sys/class/bluetooth:/sys/class/bluetooth:ro
65
- # - /sys/devices:/sys/devices:ro
66
-
67
- # Optional: Watchtower for automatic updates
68
- # Uncomment this service to enable daily checks for new images
69
- # watchtower:
70
- # image: containrrr/watchtower:latest
71
- # container_name: watchtower-mmrelay
72
- # restart: unless-stopped
73
- # volumes:
74
- # - /var/run/docker.sock:/var/run/docker.sock
75
- # environment:
76
- # - WATCHTOWER_CLEANUP=true
77
- # - WATCHTOWER_INCLUDE_STOPPED=true
78
- # - WATCHTOWER_SCHEDULE=0 0 2 * * * # Daily at 2 AM
79
- # - WATCHTOWER_TIMEOUT=30s
80
- # command: meshtastic-matrix-relay
11
+ # Mount your config directory - create ~/.mmrelay/config.yaml first
12
+ # See docs/DOCKER.md for setup instructions
13
+ # For SELinux systems (RHEL/CentOS/Fedora), add :Z flag to prevent permission denied errors
14
+ - ${MMRELAY_HOME:-$HOME}/.mmrelay/config.yaml:/app/config.yaml:ro,Z
15
+ - ${MMRELAY_HOME:-$HOME}/.mmrelay:/app/data:Z
16
+ # For non-SELinux systems, you can use:
17
+ # - ${MMRELAY_HOME:-$HOME}/.mmrelay/config.yaml:/app/config.yaml:ro
18
+ # - ${MMRELAY_HOME:-$HOME}/.mmrelay:/app/data
19
+ # Tip: For correct permissions and paths, ensure UID, GID, and MMRELAY_HOME are set in a .env file or exported
@@ -1,65 +1,19 @@
1
1
  services:
2
2
  mmrelay:
3
3
  build: .
4
- container_name: meshtastic-matrix-relay
4
+ container_name: mmrelay # Updated for consistent branding
5
5
  restart: unless-stopped
6
+ stop_grace_period: 30s
6
7
  user: "${UID:-1000}:${GID:-1000}"
7
-
8
8
  environment:
9
- - TZ=UTC
10
- - PYTHONUNBUFFERED=1
11
- - MPLCONFIGDIR=/tmp/matplotlib
12
-
13
- # Matrix Authentication: Use 'mmrelay auth login' on host system to create credentials.json
14
- # The credentials file will be automatically loaded from the volume mount below
15
-
16
- # Meshtastic Connection Settings - Uncomment and configure as needed
17
- # TCP Connection (most common)
18
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=tcp
19
- # - MMRELAY_MESHTASTIC_HOST=192.168.1.100
20
- # - MMRELAY_MESHTASTIC_PORT=4403 # Default port
21
-
22
- # Serial Connection (uncomment for serial)
23
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=serial
24
- # - MMRELAY_MESHTASTIC_SERIAL_PORT=/dev/ttyUSB0
25
-
26
- # BLE Connection (uncomment for Bluetooth)
27
- # - MMRELAY_MESHTASTIC_CONNECTION_TYPE=ble
28
- # - MMRELAY_MESHTASTIC_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
29
-
30
- # Meshtastic Operational Settings
31
- # - MMRELAY_MESHTASTIC_BROADCAST_ENABLED=true
32
- # - MMRELAY_MESHTASTIC_MESHNET_NAME=My Mesh Network
33
- # - MMRELAY_MESHTASTIC_MESSAGE_DELAY=2.2 # Minimum 2.0 seconds
34
-
35
- # System Configuration
36
- # - MMRELAY_LOGGING_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
37
- # - MMRELAY_LOG_FILE=/app/data/logs/mmrelay.log # Enables file logging
38
- # - MMRELAY_DATABASE_PATH=/app/data/meshtastic.sqlite
39
-
40
- # Note: Environment variables for Meshtastic, logging, and database settings take precedence over config.yaml
41
-
9
+ - TZ=UTC # Set timezone (PYTHONUNBUFFERED and MPLCONFIGDIR are set in Dockerfile)
42
10
  volumes:
43
- # Map entire ~/.mmrelay directory to /app/data to maintain proper structure
44
- # This includes config.yaml, plugins/, data/, logs/, credentials.json, and any other subdirectories
45
- # The --data-dir parameter in CMD points to /app/data
46
- # Create config.yaml first with: make config
47
- - ${MMRELAY_HOME}/.mmrelay:/app/data
48
-
49
- # For TCP connections (most common) - Meshtastic typically uses port 4403
50
- ports:
51
- - 4403:4403
52
-
53
- # For serial connections, uncomment the device you need:
54
- # devices:
55
- # - /dev/ttyUSB0:/dev/ttyUSB0
56
- # - /dev/ttyACM0:/dev/ttyACM0
57
-
58
- # For BLE connections, uncomment these:
59
- # privileged: true
60
- # network_mode: host
61
- # Additional volumes for BLE (add to existing volumes section above):
62
- # - /var/run/dbus:/var/run/dbus:ro
63
- # - /sys/bus/usb:/sys/bus/usb:ro
64
- # - /sys/class/bluetooth:/sys/class/bluetooth:ro
65
- # - /sys/devices:/sys/devices:ro
11
+ # Mount your config directory - create ~/.mmrelay/config.yaml first
12
+ # Run 'make config' to set up the files
13
+ # For SELinux systems (RHEL/CentOS/Fedora), add :Z flag to prevent permission denied errors
14
+ - ${MMRELAY_HOME:-$HOME}/.mmrelay/config.yaml:/app/config.yaml:ro,Z
15
+ - ${MMRELAY_HOME:-$HOME}/.mmrelay:/app/data:Z
16
+ # For non-SELinux systems, you can use:
17
+ # - ${MMRELAY_HOME:-$HOME}/.mmrelay/config.yaml:/app/config.yaml:ro
18
+ # - ${MMRELAY_HOME:-$HOME}/.mmrelay:/app/data
19
+ # Tip: For correct permissions and paths, ensure UID, GID, and MMRELAY_HOME are set in a .env file or exported
@@ -59,7 +59,7 @@ meshtastic:
59
59
 
60
60
  # Message prefix customization (Matrix → Meshtastic direction)
61
61
  #prefix_enabled: true # Enable username prefixes on messages sent to mesh (e.g., "Alice[M]: message")
62
- #prefix_format: "{display5}[M]: " # Default format. See EXTRA_CONFIGURATION.md for all variables.
62
+ #prefix_format: "{display5}[M]: " # Default format. See ADVANCED_CONFIGURATION.md for all variables.
63
63
 
64
64
  logging:
65
65
  level: info
@@ -0,0 +1,349 @@
1
+ """
2
+ Windows-specific utilities for MMRelay.
3
+
4
+ This module provides Windows-specific functionality and workarounds
5
+ for better compatibility and user experience on Windows systems.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ from typing import Optional
11
+
12
+ from mmrelay.constants.app import WINDOWS_PLATFORM
13
+
14
+
15
+ def is_windows() -> bool:
16
+ """
17
+ Return True if the current process is running on a Windows platform.
18
+
19
+ Checks common platform indicators (os.name == "nt" or sys.platform == WINDOWS_PLATFORM)
20
+ and returns a boolean accordingly.
21
+
22
+ Returns:
23
+ bool: True when running on Windows, otherwise False.
24
+ """
25
+ return os.name == "nt" or sys.platform == WINDOWS_PLATFORM
26
+
27
+
28
+ def setup_windows_console() -> None:
29
+ """
30
+ Configure the Windows console for UTF-8 output and ANSI (VT100) color support.
31
+
32
+ Best-effort operation: on Windows this attempts to set stdout/stderr encoding to UTF-8
33
+ (if supported) and enable Virtual Terminal Processing so ANSI color sequences and
34
+ Unicode render correctly. No-op on non-Windows platforms; failures are silently ignored.
35
+ """
36
+ if not is_windows():
37
+ return
38
+
39
+ try:
40
+ # Enable UTF-8 output on Windows
41
+ if hasattr(sys.stdout, "reconfigure"):
42
+ sys.stdout.reconfigure(encoding="utf-8")
43
+ if hasattr(sys.stderr, "reconfigure"):
44
+ sys.stderr.reconfigure(encoding="utf-8")
45
+
46
+ # Enable ANSI color codes on Windows 10+
47
+ import ctypes
48
+
49
+ kernel32 = ctypes.windll.kernel32
50
+ ENABLE_VTP = 0x0004 # ENABLE_VIRTUAL_TERMINAL_PROCESSING
51
+ for handle in (-11, -12): # STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
52
+ h = kernel32.GetStdHandle(handle)
53
+ if h is not None and h != -1:
54
+ mode = ctypes.c_uint()
55
+ if kernel32.GetConsoleMode(h, ctypes.byref(mode)):
56
+ kernel32.SetConsoleMode(h, mode.value | ENABLE_VTP)
57
+ except (OSError, AttributeError):
58
+ # If console setup fails, continue without it
59
+ # This is expected on non-Windows systems or older Windows versions
60
+ return
61
+
62
+
63
+ def get_windows_error_message(error: Exception) -> str:
64
+ """
65
+ Return a Windows-tailored, user-friendly message for common filesystem and network exceptions.
66
+
67
+ If not running on Windows this returns str(error) unchanged. For Windows, the function recognizes
68
+ permission errors (PermissionError or OSError with EACCES/EPERM), missing-file errors
69
+ (FileNotFoundError or OSError with ENOENT), and common network-related OSErrors
70
+ (EHOSTUNREACH, ENETDOWN, ENETUNREACH, ECONNREFUSED, ETIMEDOUT) and returns guidance specific
71
+ to each case (possible causes and suggested next steps). For other exceptions it returns
72
+ str(error).
73
+
74
+ Parameters:
75
+ error (Exception): The exception to translate into a user-facing message.
76
+
77
+ Returns:
78
+ str: A user-oriented error message; either a Windows-specific guidance string or the
79
+ original exception string for unhandled cases or non-Windows platforms.
80
+ """
81
+ if not is_windows():
82
+ return str(error)
83
+
84
+ import errno as _errno
85
+
86
+ # Use exception types and errno codes for more robust error detection
87
+ if isinstance(error, PermissionError) or (
88
+ isinstance(error, OSError) and error.errno in {_errno.EACCES, _errno.EPERM}
89
+ ):
90
+ return (
91
+ f"Permission denied: {error}\n"
92
+ "This may be caused by:\n"
93
+ "• Antivirus software blocking the operation\n"
94
+ "• Windows User Account Control (UAC) restrictions\n"
95
+ "• File being used by another process\n"
96
+ "Try running as administrator or check antivirus settings."
97
+ )
98
+ elif isinstance(error, FileNotFoundError) or (
99
+ isinstance(error, OSError) and error.errno in {_errno.ENOENT}
100
+ ):
101
+ return (
102
+ f"File not found: {error}\n"
103
+ "This may be caused by:\n"
104
+ "• Incorrect file path (check for spaces or special characters)\n"
105
+ "• File moved or deleted by antivirus software\n"
106
+ "• Network drive disconnection\n"
107
+ "Verify the file path and check antivirus quarantine."
108
+ )
109
+ elif isinstance(error, ConnectionError) or (
110
+ isinstance(error, OSError)
111
+ and error.errno
112
+ in {
113
+ _errno.EHOSTUNREACH,
114
+ _errno.ENETDOWN,
115
+ _errno.ENETUNREACH,
116
+ _errno.ECONNREFUSED,
117
+ _errno.ETIMEDOUT,
118
+ }
119
+ ):
120
+ return (
121
+ f"Network error: {error}\n"
122
+ "This may be caused by:\n"
123
+ "• Windows Firewall blocking the connection\n"
124
+ "• Antivirus software blocking network access\n"
125
+ "• VPN or proxy configuration issues\n"
126
+ "Check firewall settings and antivirus network protection."
127
+ )
128
+ else:
129
+ return str(error)
130
+
131
+
132
+ def check_windows_requirements() -> Optional[str]:
133
+ """
134
+ Return a multi-line warning string when common Windows environment issues are detected; otherwise None.
135
+
136
+ Performs Windows-only checks:
137
+ - Python version: warns if running on Python < 3.9.
138
+ - Virtual environment: warns if the process does not appear to be inside a venv/pipx.
139
+ - Current working directory length: warns if the cwd path length exceeds 200 characters.
140
+
141
+ Returns:
142
+ Optional[str]: A human-readable, multi-line warning message when one or more checks trigger;
143
+ returns None if running on a non-Windows platform or no issues are found.
144
+ """
145
+ if not is_windows():
146
+ return None
147
+
148
+ warnings = []
149
+
150
+ # Check Python version for Windows compatibility
151
+ if sys.version_info < (3, 9):
152
+ warnings.append(
153
+ "Python 3.9+ is recommended on Windows for better compatibility"
154
+ )
155
+
156
+ # Check if running in a virtual environment
157
+ if not hasattr(sys, "real_prefix") and not (
158
+ hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
159
+ ):
160
+ warnings.append(
161
+ "Consider using a virtual environment (venv) or pipx for better isolation"
162
+ )
163
+
164
+ # Check for common Windows path issues
165
+ if len(os.getcwd()) > 200:
166
+ warnings.append(
167
+ "Current directory path is very long - this may cause issues on Windows"
168
+ )
169
+
170
+ if warnings:
171
+ return "Windows compatibility warnings:\n• " + "\n• ".join(warnings)
172
+
173
+ return None
174
+
175
+
176
+ def test_config_generation_windows(args=None) -> dict:
177
+ """
178
+ Run Windows-only diagnostics for MMRelay configuration generation.
179
+
180
+ Performs four checks and returns a dictionary with per-test results and an overall status:
181
+ - sample_config_path: verifies mmrelay.tools.get_sample_config_path() exists.
182
+ - importlib_resources: attempts to read mmrelay.tools/sample_config.yaml via importlib.resources.
183
+ - config_paths: calls mmrelay.config.get_config_paths(args) and reports the returned paths.
184
+ - directory_creation: ensures parent directories for the config paths exist (creates them if missing).
185
+
186
+ Parameters:
187
+ args (optional): Forwarded to mmrelay.config.get_config_paths; typically CLI-style arguments or None.
188
+
189
+ Returns:
190
+ dict: Diagnostic results with these keys:
191
+ - sample_config_path, importlib_resources, config_paths, directory_creation:
192
+ dict objects with "status" ("ok" or "error") and "details" (string).
193
+ - overall_status: one of "ok" (no errors), "partial" (1–2 errors), or "error" (3+ errors).
194
+ If called on a non-Windows platform, returns {"error": "This function is only for Windows systems"}.
195
+
196
+ Notes:
197
+ - The function does not raise on expected failures; errors are reported in the returned dict.
198
+ - Directory creation test may create directories on disk when missing.
199
+ """
200
+ if not is_windows():
201
+ return {"error": "This function is only for Windows systems"}
202
+
203
+ results = {
204
+ "sample_config_path": {"status": "unknown", "details": ""},
205
+ "importlib_resources": {"status": "unknown", "details": ""},
206
+ "config_paths": {"status": "unknown", "details": ""},
207
+ "directory_creation": {"status": "unknown", "details": ""},
208
+ "overall_status": "unknown",
209
+ }
210
+
211
+ try:
212
+ # Test 1: Sample config path
213
+ try:
214
+ from mmrelay.tools import get_sample_config_path
215
+
216
+ sample_path = get_sample_config_path()
217
+ if os.path.exists(sample_path):
218
+ results["sample_config_path"] = {
219
+ "status": "ok",
220
+ "details": f"Found at: {sample_path}",
221
+ }
222
+ else:
223
+ results["sample_config_path"] = {
224
+ "status": "error",
225
+ "details": f"Not found at: {sample_path}",
226
+ }
227
+ except (
228
+ ImportError,
229
+ OSError,
230
+ FileNotFoundError,
231
+ AttributeError,
232
+ TypeError,
233
+ ) as e:
234
+ results["sample_config_path"] = {"status": "error", "details": str(e)}
235
+
236
+ # Test 2: importlib.resources fallback
237
+ try:
238
+ import importlib.resources
239
+
240
+ content = (
241
+ importlib.resources.files("mmrelay.tools")
242
+ .joinpath("sample_config.yaml")
243
+ .read_text()
244
+ )
245
+ results["importlib_resources"] = {
246
+ "status": "ok",
247
+ "details": f"Content length: {len(content)} chars",
248
+ }
249
+ except (ImportError, OSError, FileNotFoundError) as e:
250
+ results["importlib_resources"] = {"status": "error", "details": str(e)}
251
+
252
+ # Test 3: Config paths
253
+ try:
254
+ from mmrelay.config import get_config_paths
255
+
256
+ paths = get_config_paths(args)
257
+ results["config_paths"] = {"status": "ok", "details": f"Paths: {paths}"}
258
+ except (ImportError, OSError) as e:
259
+ results["config_paths"] = {"status": "error", "details": str(e)}
260
+
261
+ # Test 4: Directory creation
262
+ try:
263
+ from mmrelay.config import get_config_paths
264
+
265
+ paths = get_config_paths(args)
266
+ created_dirs = []
267
+ for path in paths:
268
+ dir_path = os.path.dirname(path)
269
+ if not os.path.exists(dir_path):
270
+ os.makedirs(dir_path, exist_ok=True)
271
+ created_dirs.append(dir_path)
272
+ results["directory_creation"] = {
273
+ "status": "ok",
274
+ "details": f"Created: {created_dirs}",
275
+ }
276
+ except OSError as e:
277
+ results["directory_creation"] = {"status": "error", "details": str(e)}
278
+
279
+ # Determine overall status
280
+ error_count = sum(
281
+ 1
282
+ for r in results.values()
283
+ if isinstance(r, dict) and r.get("status") == "error"
284
+ )
285
+ if error_count == 0:
286
+ results["overall_status"] = "ok"
287
+ elif error_count < 3: # If at least one fallback works
288
+ results["overall_status"] = "partial"
289
+ else:
290
+ results["overall_status"] = "error"
291
+
292
+ except OSError as e:
293
+ results["overall_status"] = "error"
294
+ results["error"] = str(e)
295
+
296
+ return results
297
+
298
+
299
+ def get_windows_install_guidance() -> str:
300
+ """
301
+ Return a Windows-specific installation and troubleshooting guide as a formatted string.
302
+
303
+ The returned text contains recommended installation methods, common Windows-specific problems with actionable remedies, and troubleshooting tips for configuration and runtime issues. It is safe to display directly to end users or include in logs/help output.
304
+
305
+ Returns:
306
+ str: Multiline guidance text suited for Windows users.
307
+ """
308
+ return """
309
+ Windows Installation & Troubleshooting Guide:
310
+
311
+ 📦 Recommended Installation:
312
+ pipx install mmrelay
313
+ (pipx provides better isolation and fewer conflicts)
314
+
315
+ 🔧 If pipx is not available:
316
+ pip install --user mmrelay
317
+ (installs to user directory, avoiding system conflicts)
318
+
319
+ ⚠️ Common Windows Issues:
320
+
321
+ 1. "ModuleNotFoundError: No module named 'pkg_resources'"
322
+ Solution: pip install --upgrade setuptools
323
+ Alternative: Use 'python -m mmrelay' instead of 'mmrelay'
324
+
325
+ 2. "Access denied" or permission errors
326
+ Solution: Run command prompt as administrator
327
+ Or: Use --user flag with pip
328
+
329
+ 3. "SSL certificate verify failed"
330
+ Solution: Update certificates or use --trusted-host flag
331
+
332
+ 4. Antivirus blocking installation/execution
333
+ Solution: Add Python and pip to antivirus exclusions
334
+
335
+ 5. Long path issues
336
+ Solution: Enable long path support in Windows 10+
337
+ Or: Use shorter installation directory
338
+
339
+ 6. Config generation fails
340
+ Solution: Check if sample_config.yaml is accessible
341
+ Alternative: Manually create config file from documentation
342
+
343
+ 🆘 Need Help?
344
+ • Check Windows Event Viewer for detailed error logs
345
+ • Temporarily disable antivirus for testing
346
+ • Use Windows PowerShell instead of Command Prompt
347
+ • Consider using Windows Subsystem for Linux (WSL)
348
+ • Test config generation: 'python -m mmrelay config diagnose'
349
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mmrelay
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: Bridge between Meshtastic mesh networks and Matrix chat rooms
5
5
  Home-page: https://github.com/jeremiah-k/meshtastic-matrix-relay
6
6
  Author: Geoff Whittington, Jeremiah K., and contributors
@@ -23,15 +23,15 @@ Requires-Dist: Pillow==11.3.0
23
23
  Requires-Dist: matrix-nio==0.25.2
24
24
  Requires-Dist: matplotlib==3.10.1
25
25
  Requires-Dist: requests==2.32.5
26
- Requires-Dist: markdown==3.8.2
26
+ Requires-Dist: markdown==3.9
27
27
  Requires-Dist: bleach==6.2.0
28
28
  Requires-Dist: haversine==2.9.0
29
29
  Requires-Dist: schedule==1.2.2
30
- Requires-Dist: platformdirs==4.3.8
30
+ Requires-Dist: platformdirs==4.4.0
31
31
  Requires-Dist: py-staticmaps>=0.4.0
32
32
  Requires-Dist: psutil>=5.8.0
33
33
  Requires-Dist: rich==14.1.0
34
- Requires-Dist: setuptools==80.9.0
34
+ Requires-Dist: setuptools>=80.9.0
35
35
  Provides-Extra: e2e
36
36
  Requires-Dist: matrix-nio[e2e]==0.25.2; extra == "e2e"
37
37
  Requires-Dist: python-olm; extra == "e2e"
@@ -48,7 +48,7 @@ Dynamic: requires-dist
48
48
  Dynamic: requires-python
49
49
  Dynamic: summary
50
50
 
51
- # M<>M Relay
51
+ # MMRelay
52
52
 
53
53
  ## (Meshtastic <=> Matrix Relay)
54
54
 
@@ -84,7 +84,7 @@ MMRelay supports multiple deployment methods including Docker, pip installation,
84
84
 
85
85
  ## Plugins
86
86
 
87
- M<>M Relay supports plugins for extending its functionality, enabling customization and enhancement of the relay to suit specific needs.
87
+ MMRelay supports plugins for extending its functionality, enabling customization and enhancement of the relay to suit specific needs.
88
88
 
89
89
  ### Core Plugins
90
90
 
@@ -133,7 +133,7 @@ Plugins make it easy to extend functionality without modifying the core program.
133
133
 
134
134
  ## Getting Started with Matrix
135
135
 
136
- See our Wiki page [Getting Started With Matrix & MM Relay](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Getting-Started-With-Matrix-&-MM-Relay).
136
+ See our Wiki page [Getting Started With Matrix & MMRelay](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Getting-Started-With-Matrix-&-MM-Relay).
137
137
 
138
138
  ---
139
139
 
@@ -0,0 +1,48 @@
1
+ mmrelay/__init__.py,sha256=vnKf5ECNyF96YnmUUlBJS4Xwn1kTGb2VbI75clrcZV4,120
2
+ mmrelay/__main__.py,sha256=Z839i5jxZmhdoPvR1-reWoQL4Xpmty81p8TsTKsJLC8,814
3
+ mmrelay/cli.py,sha256=PNUnt1K83QI6vtPwc6hsL5Iaw9OaNDh5aS1Rlid64KE,79403
4
+ mmrelay/cli_utils.py,sha256=h0JKhU_sToO2_Orf9ddO8x07_L1k201V61yXydfU2es,28887
5
+ mmrelay/config.py,sha256=XOmQomLuQRl6MnvKOn8tSjU8jaDp6rurjtgacRkhFaw,38330
6
+ mmrelay/db_utils.py,sha256=utt254MipaIRTaGqSAe7N9L_S7eIPSnQsOQj6Gk2E3U,22502
7
+ mmrelay/e2ee_utils.py,sha256=krRXJzeo_tpW9QfcmpZe0A3kPoQ14tUrDQW7dxsx2sc,16656
8
+ mmrelay/log_utils.py,sha256=psTzfRUTp1aVIE8U-7bzS7qc1ulU9EavqAEbDt8hUQA,9126
9
+ mmrelay/main.py,sha256=mF1D7Psbk46CIOfGEtG3onG3Yn5Zk-3oZF_t2pTv1JY,16785
10
+ mmrelay/matrix_utils.py,sha256=56VTa1ptf5eY-mcwUMTaAw09fztkoMs4j-UTi6nRUsY,134552
11
+ mmrelay/meshtastic_utils.py,sha256=IJp0xD6HSqNEmOymVtgJaExtP83KhZrCM_SWDPqEIvU,48821
12
+ mmrelay/message_queue.py,sha256=Ze9l_vDQBiWUX68jFvBbuMTJzyfcU4sW1jRyrN2tjC8,28005
13
+ mmrelay/plugin_loader.py,sha256=iXUpLGyjir7sfxtnL1REHdg5i5ZGWaHO_6sRQqf_JCE,59052
14
+ mmrelay/runtime_utils.py,sha256=u8DtpfI-U7Ip3SAwjn214WfMTzc-xr5wffjN0i7WBZc,1261
15
+ mmrelay/setup_utils.py,sha256=TNB2lRewKjt5aPFwVvQQeYZuE0eWvz3krn2pn-GZJvg,32738
16
+ mmrelay/windows_utils.py,sha256=cXqXIszPAva-GLSY0Xxxai7PO7UBryAb9aPhdHdDo0I,13064
17
+ mmrelay/constants/__init__.py,sha256=M8AXeIcS1JuS8OwmfTmhcCOkAz5XmWlNQ53GBxYOx94,1494
18
+ mmrelay/constants/app.py,sha256=iNKqQMp5WZSfzsuRXYZ00znVm_ZyfwqiWMQgAblG6rY,725
19
+ mmrelay/constants/config.py,sha256=B1A_OZLLNXHM9rHOwc01ZaJBvFugR2eXlhYYl4nUxlY,2479
20
+ mmrelay/constants/database.py,sha256=4cHfYfBePDUUtVSflrWyStcxKSQv7VE-jSrb1IzAjls,646
21
+ mmrelay/constants/formats.py,sha256=cjbrfNNFCKoGSFsFHR1QQDEQudiGquA9MUapfm0_ZNI,494
22
+ mmrelay/constants/messages.py,sha256=Reu_-6gZGGZQVP6BuqBm01QBhVTFjHVRQSPTUcQJG2Q,1531
23
+ mmrelay/constants/network.py,sha256=QjROOAMxcP1pA1F_gUtuXzm2tORCqo5koqZbwrZRSns,1186
24
+ mmrelay/constants/queue.py,sha256=yyWSrtq06b5GWzZwdl6IFtrMvxEuF9PdKSNPh8DdL2M,565
25
+ mmrelay/plugins/__init__.py,sha256=KVMQIXRhe0wlGj4O3IZ0vOIQRKFkfPYejHXhJL17qrc,51
26
+ mmrelay/plugins/base_plugin.py,sha256=Nh_zz-Z49qYatS4i38C2bLOl1sNDUgWsqpD8NLJdnl0,20807
27
+ mmrelay/plugins/debug_plugin.py,sha256=adX0cRJHUEDLldajybPfiRDDlvytkZe5aN_dSgNKP2Y,870
28
+ mmrelay/plugins/drop_plugin.py,sha256=x4S-e0Muun2Dy1H2qwRMTBB1ptLmy7ZZJhgPu-KefGs,5394
29
+ mmrelay/plugins/health_plugin.py,sha256=svV_GfpAVL0QhiVzi3PVZ1mNpsOL1NHSmkRF-Mn_ExE,2250
30
+ mmrelay/plugins/help_plugin.py,sha256=S7nBhsANK46Zv9wPHOVegPGcuYGMErBsxAnrRlSSCwg,2149
31
+ mmrelay/plugins/map_plugin.py,sha256=eHV_t3TFcypBD4xT_OQx0hD6_iGkLJOADjwYVny0PvE,11292
32
+ mmrelay/plugins/mesh_relay_plugin.py,sha256=O5I_5H4Y8CSonuLoS4lGhlNee1F7RVmSv551WCSsufM,8477
33
+ mmrelay/plugins/nodes_plugin.py,sha256=RDabzyG5hKG5aYWecsRUcLSjMCCv6Pngmq2Qpld1A1U,2903
34
+ mmrelay/plugins/ping_plugin.py,sha256=8uFnT3qfO3RBaTUOx348voIfKpzXB3zTfcT6Gtfc8kM,4070
35
+ mmrelay/plugins/telemetry_plugin.py,sha256=8SxWv4BLXMUTbiVaD3MjlMMdQyS7S_1OfLlVNAUMSO0,6306
36
+ mmrelay/plugins/weather_plugin.py,sha256=ZmTNlkEjeCvZWHlO7VMend3vnj4h2qWeeU4RUQJY2vM,14183
37
+ mmrelay/tools/__init__.py,sha256=WFjDQjdevgg19_zT6iEoL29rvb1JPqYSd8708Jn5D7A,838
38
+ mmrelay/tools/mmrelay.service,sha256=6_TAskmTh9pXQSDRDeh0EXl2BfsUgm9Q3W9ob5tWCS8,600
39
+ mmrelay/tools/sample-docker-compose-prebuilt.yaml,sha256=RT3IWA4DuLfIB5C7fUT1cDaYhOAxXiUjBan1M6PlvKc,958
40
+ mmrelay/tools/sample-docker-compose.yaml,sha256=pbE9nXSA9DcEbdwhCQ0mZzzmhYRi3L9y8crx3a_YrTE,940
41
+ mmrelay/tools/sample.env,sha256=RP-o3rX3jnEIrVG2rqCZq31O1yRXou4HcGrXWLVbKKw,311
42
+ mmrelay/tools/sample_config.yaml,sha256=odAeiU-wesWuwnZGyXzVjxaXVYc26p8QI1HOEA-Tvco,6396
43
+ mmrelay-1.2.2.dist-info/licenses/LICENSE,sha256=aB_07MhnK-bL5WLI1ucXLUSdW_yBVoepPRYB0kaAOl8,35204
44
+ mmrelay-1.2.2.dist-info/METADATA,sha256=JKh3iEvvM3Tgr01iAyWuhPPxOkMcpxgPgXQFXgsLtyY,6167
45
+ mmrelay-1.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
+ mmrelay-1.2.2.dist-info/entry_points.txt,sha256=SJZwGUOEpQ-qx4H8UL4xKFnKeInGUaZNW1I0ddjK7Ws,45
47
+ mmrelay-1.2.2.dist-info/top_level.txt,sha256=B_ZLCRm7NYAmI3PipRUyHGymP-C-q16LSeMGzmqJfo4,8
48
+ mmrelay-1.2.2.dist-info/RECORD,,