Skip to content
Open
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
4 changes: 4 additions & 0 deletions config.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,10 @@ require_path_bytes_greater_or_equal_to = 0
# Optional response when rejected by path-byte requirement; leave empty for silent reject
require_path_bytes_failure_response =

# Append total distance traveled (sender → repeaters → bot) to path responses (default: true)
# Silently omitted when any repeater in the path has no known coordinates.
show_path_distance = true

# Enable "p" shortcut for path command (similar to "t" for test command)
# true: Respond to just "p" or "p <path_data>" as a shortcut for "path" (default)
# false: Only respond to "path", "decode", or "route" keywords
Expand Down
42 changes: 42 additions & 0 deletions modules/commands/path_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ def __init__(self, bot):
self.medium_confidence_symbol = bot.config.get('Path_Command', 'medium_confidence_symbol', fallback='📍')
self.low_confidence_symbol = bot.config.get('Path_Command', 'low_confidence_symbol', fallback='❓')

self.show_path_distance = self.get_config_value(
'Path_Command', 'show_path_distance', fallback=True, value_type='bool'
)

# Check if "p" shortcut is enabled (on by default)
self.enable_p_shortcut = bot.config.getboolean('Path_Command', 'enable_p_shortcut', fallback=True)
if self.enable_p_shortcut:
Expand Down Expand Up @@ -1709,6 +1713,11 @@ def _format_path_response(self, node_ids: list[str], repeater_info: dict[str, di

lines.append(line)

if self.show_path_distance:
km, missing = self._calculate_full_path_km(node_ids)
if km is not None and missing == 0:
lines.append(self.translate('commands.path.distance_traveled', km=km))

# Return all lines - let _send_path_response handle the splitting
return "\n".join(lines)

Expand Down Expand Up @@ -1819,6 +1828,39 @@ def _truncate_to_byte_length(self, text: str, max_bytes: int, ellipsis: str = ".
truncated: str = text_bytes[:available].decode('utf-8', errors='ignore')
return truncated + ellipsis

def _calculate_full_path_km(self, node_ids: list[str]) -> tuple[Optional[float], int]:
"""Sum distance sender → repeaters → bot. Returns (km, missing_count).

missing_count is the number of node_ids with no location in the DB.
km is None when fewer than 2 waypoints have known coordinates.
"""
waypoints: list[tuple[float, float]] = []
missing = 0

sender_loc = self._get_sender_location()
if sender_loc:
waypoints.append(sender_loc)

for node_id in node_ids:
loc = self._get_node_location(node_id)
if loc:
waypoints.append(loc)
else:
missing += 1

if self.bot_latitude is not None and self.bot_longitude is not None:
waypoints.append((self.bot_latitude, self.bot_longitude))

if len(waypoints) < 2:
return None, missing

total = sum(
calculate_distance(waypoints[i][0], waypoints[i][1],
waypoints[i + 1][0], waypoints[i + 1][1])
for i in range(len(waypoints) - 1)
)
return round(total, 1), missing

def get_help(self) -> str:
"""Get help text for the path command"""
return self.translate('commands.path.help')
Expand Down
3 changes: 2 additions & 1 deletion translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Unbekannt",
"repeater_resolution_deferred": "Pfad: {path}\n\n💡 Hinweis: Repeater-Erkennung erfordert Pfade mit {minimum_path_bytes} Byte(s) pro Hop."
"repeater_resolution_deferred": "Pfad: {path}\n\n💡 Hinweis: Repeater-Erkennung erfordert Pfade mit {minimum_path_bytes} Byte(s) pro Hop.",
"distance_traveled": "📏 {km} km zurückgelegt"
},
"prefix": {
"description": "Repeater nach zweistelligem Präfix suchen (z.B. 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/en-GB.json
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Unknown",
"repeater_resolution_deferred": "Path: {path}\n\n💡 Tip: Repeater identification requires {minimum_path_bytes}-byte paths."
"repeater_resolution_deferred": "Path: {path}\n\n💡 Tip: Repeater identification requires {minimum_path_bytes}-byte paths.",
"distance_traveled": "📏 {km} km travelled"
},
"prefix": {
"description": "Look up repeaters by two-character prefix (e.g., 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Unknown",
"repeater_resolution_deferred": "Path: {path}\n\n💡 Tip: Repeater identification requires {minimum_path_bytes}-byte paths."
"repeater_resolution_deferred": "Path: {path}\n\n💡 Tip: Repeater identification requires {minimum_path_bytes}-byte paths.",
"distance_traveled": "📏 {km} km traveled"
},
"multitest": {
"description": "Listens for 6 seconds and collects all unique paths from incoming messages with the same packet hash",
Expand Down
3 changes: 2 additions & 1 deletion translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Desconocido",
"repeater_resolution_deferred": "Ruta: {path}\n\n💡 Consejo: la identificación de repetidores requiere rutas de {minimum_path_bytes} byte(s) por salto."
"repeater_resolution_deferred": "Ruta: {path}\n\n💡 Consejo: la identificación de repetidores requiere rutas de {minimum_path_bytes} byte(s) por salto.",
"distance_traveled": "📏 {km} km recorridos"
},
"prefix": {
"description": "Buscar repetidores por prefijo de dos caracteres (ej., 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/fr-CA.json
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Inconnu",
"repeater_resolution_deferred": "Chemin : {path}\n\n💡 Astuce : l'identification des répéteurs exige des chemins de {minimum_path_bytes} octet(s) par saut."
"repeater_resolution_deferred": "Chemin : {path}\n\n💡 Astuce : l'identification des répéteurs exige des chemins de {minimum_path_bytes} octet(s) par saut.",
"distance_traveled": "📏 {km} km parcourus"
},
"prefix": {
"description": "Rechercher des répéteurs par préfixe de deux caractères (ex : 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Inconnu",
"repeater_resolution_deferred": "Chemin : {path}\n\n💡 Astuce : l'identification des répéteurs exige des chemins de {minimum_path_bytes} octet(s) par saut."
"repeater_resolution_deferred": "Chemin : {path}\n\n💡 Astuce : l'identification des répéteurs exige des chemins de {minimum_path_bytes} octet(s) par saut.",
"distance_traveled": "📏 {km} km parcourus"
},
"prefix": {
"description": "Recherche répéteurs par préfixe 2 caractères (ex: 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Onbekend",
"repeater_resolution_deferred": "Pad: {path}\n\n💡 Tip: repeateridentificatie vereist paden met {minimum_path_bytes} byte(s) per hop."
"repeater_resolution_deferred": "Pad: {path}\n\n💡 Tip: repeateridentificatie vereist paden met {minimum_path_bytes} byte(s) per hop.",
"distance_traveled": "📏 {km} km afgelegd"
},
"prefix": {
"description": "Zoek repeaters op twee-karakter prefix (bijv. 'prefix 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Nieznana",
"repeater_resolution_deferred": "Ścieżka: {path}\n\n💡 Wskazówka: identyfikacja repeaterów wymaga ścieżek z {minimum_path_bytes} bajt(ami) na skok."
"repeater_resolution_deferred": "Ścieżka: {path}\n\n💡 Wskazówka: identyfikacja repeaterów wymaga ścieżek z {minimum_path_bytes} bajt(ami) na skok.",
"distance_traveled": "📏 {km} km pokonano"
},
"multitest": {
"description": "Nasłuchuje 6 sekund aby zebrać unikalne ścieżki z przychodzących wiadomości z tym samym hash'em pakietu",
Expand Down
3 changes: 2 additions & 1 deletion translations/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Desconhecido",
"repeater_resolution_deferred": "Caminho: {path}\n\n💡 Dica: a identificação de repetidores exige caminhos com {minimum_path_bytes} byte(s) por salto."
"repeater_resolution_deferred": "Caminho: {path}\n\n💡 Dica: a identificação de repetidores exige caminhos com {minimum_path_bytes} byte(s) por salto.",
"distance_traveled": "📏 {km} km percorridos"
},
"prefix": {
"description": "Procurar repetidores por prefixo de dois caracteres (ex: 'prefixo 1A')",
Expand Down
3 changes: 2 additions & 1 deletion translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@
"continuation_end": "\n...",
"truncation": "...",
"unknown_name": "Desconhecido",
"repeater_resolution_deferred": "Caminho: {path}\n\n💡 Dica: a identificação de repetidores exige caminhos com {minimum_path_bytes} byte(s) por salto."
"repeater_resolution_deferred": "Caminho: {path}\n\n💡 Dica: a identificação de repetidores exige caminhos com {minimum_path_bytes} byte(s) por salto.",
"distance_traveled": "📏 {km} km percorridos"
},
"prefix": {
"description": "Pesquisar repetidores por prefixo de dois caracteres (ex: 'prefixo 1A')",
Expand Down