meshcore-cli 1.1.37__py3-none-any.whl → 1.1.39__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.
- meshcore_cli/meshcore_cli.py +121 -34
- {meshcore_cli-1.1.37.dist-info → meshcore_cli-1.1.39.dist-info}/METADATA +1 -1
- meshcore_cli-1.1.39.dist-info/RECORD +8 -0
- meshcore_cli-1.1.37.dist-info/RECORD +0 -8
- {meshcore_cli-1.1.37.dist-info → meshcore_cli-1.1.39.dist-info}/WHEEL +0 -0
- {meshcore_cli-1.1.37.dist-info → meshcore_cli-1.1.39.dist-info}/entry_points.txt +0 -0
- {meshcore_cli-1.1.37.dist-info → meshcore_cli-1.1.39.dist-info}/licenses/LICENSE +0 -0
meshcore_cli/meshcore_cli.py
CHANGED
|
@@ -23,7 +23,7 @@ from prompt_toolkit.shortcuts import radiolist_dialog
|
|
|
23
23
|
from meshcore import MeshCore, EventType, logger
|
|
24
24
|
|
|
25
25
|
# Version
|
|
26
|
-
VERSION = "v1.1.
|
|
26
|
+
VERSION = "v1.1.39"
|
|
27
27
|
|
|
28
28
|
# default ble address is stored in a config file
|
|
29
29
|
MCCLI_CONFIG_DIR = str(Path.home()) + "/.config/meshcore/"
|
|
@@ -445,6 +445,8 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
|
|
|
445
445
|
"upload_contact" : None,
|
|
446
446
|
"path": None,
|
|
447
447
|
"disc_path": None,
|
|
448
|
+
"trace": None,
|
|
449
|
+
"dtrace": None,
|
|
448
450
|
"reset_path" : None,
|
|
449
451
|
"change_path" : None,
|
|
450
452
|
"change_flags" : None,
|
|
@@ -810,6 +812,15 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
|
|
|
810
812
|
await process_cmds(mc, ["cmd", contact["adv_name"], newline])
|
|
811
813
|
except IndexError:
|
|
812
814
|
print("Wrong number of parameters")
|
|
815
|
+
|
|
816
|
+
# trace called on a contact
|
|
817
|
+
elif contact["type"] > 0 and (
|
|
818
|
+
line == "trace" or line == "tr") :
|
|
819
|
+
await print_trace_to(mc, contact)
|
|
820
|
+
|
|
821
|
+
elif contact["type"] > 0 and (
|
|
822
|
+
line == "dtrace" or line == "dt") :
|
|
823
|
+
await print_disc_trace_to(mc, contact)
|
|
813
824
|
|
|
814
825
|
# same but for commands with a parameter
|
|
815
826
|
elif contact["type"] > 0 and (line.startswith("cmd ") or\
|
|
@@ -1064,6 +1075,75 @@ async def get_channels (mc, anim=False) :
|
|
|
1064
1075
|
print (" Done")
|
|
1065
1076
|
return mc.channels
|
|
1066
1077
|
|
|
1078
|
+
async def print_trace_to (mc, contact):
|
|
1079
|
+
path = contact["out_path"]
|
|
1080
|
+
path_len = contact["out_path_len"]
|
|
1081
|
+
trace = ""
|
|
1082
|
+
|
|
1083
|
+
if path_len == -1:
|
|
1084
|
+
print ("No path to destination")
|
|
1085
|
+
return
|
|
1086
|
+
|
|
1087
|
+
if contact["type"] == 2 or contact["type"] == 3:
|
|
1088
|
+
# repeater or room, can trace to the contact itself
|
|
1089
|
+
trace = contact["public_key"][0:2]
|
|
1090
|
+
|
|
1091
|
+
for i in range(0, path_len):
|
|
1092
|
+
elem = path[2*(path_len-i-1):2*(path_len-i)]
|
|
1093
|
+
trace = elem if trace=="" else f"{elem},{trace},{elem}"
|
|
1094
|
+
|
|
1095
|
+
await next_cmd(mc, ["trace", trace])
|
|
1096
|
+
|
|
1097
|
+
async def discover_path(mc, contact):
|
|
1098
|
+
await mc.ensure_contacts()
|
|
1099
|
+
res = await mc.commands.send_path_discovery(contact)
|
|
1100
|
+
if res.type == EventType.ERROR:
|
|
1101
|
+
return None
|
|
1102
|
+
else:
|
|
1103
|
+
timeout = res.payload["suggested_timeout"]/600 if not "timeout" in contact or contact['timeout']==0 else contact["timeout"]
|
|
1104
|
+
res = await mc.wait_for_event(EventType.PATH_RESPONSE, timeout=timeout)
|
|
1105
|
+
if res is None:
|
|
1106
|
+
return {"error": "timeout"}
|
|
1107
|
+
else :
|
|
1108
|
+
return res.payload
|
|
1109
|
+
|
|
1110
|
+
async def print_disc_trace_to (mc, contact):
|
|
1111
|
+
p = await discover_path(mc, contact)
|
|
1112
|
+
if p is None:
|
|
1113
|
+
print("Error discovering path")
|
|
1114
|
+
return
|
|
1115
|
+
|
|
1116
|
+
if "error" in p:
|
|
1117
|
+
print("Timeout discovering path")
|
|
1118
|
+
return
|
|
1119
|
+
|
|
1120
|
+
inp = p["in_path"]
|
|
1121
|
+
outp = p["out_path"]
|
|
1122
|
+
inp_l = int(len(inp)/2)
|
|
1123
|
+
outp_l = int(len(outp)/2)
|
|
1124
|
+
|
|
1125
|
+
trace = ""
|
|
1126
|
+
|
|
1127
|
+
for i in range(0, outp_l):
|
|
1128
|
+
elem = outp[2*i:2*(i+1)]
|
|
1129
|
+
trace = elem if trace == "" else f"{trace},{elem}"
|
|
1130
|
+
|
|
1131
|
+
if contact["type"] == 2 or contact["type"] == 3:
|
|
1132
|
+
# repeater or room, can trace to the contact itself
|
|
1133
|
+
elem = contact["public_key"][0:2]
|
|
1134
|
+
trace = elem if trace == "" else f"{trace},{elem}"
|
|
1135
|
+
|
|
1136
|
+
for i in range(0, inp_l):
|
|
1137
|
+
elem = inp[2*i:2*(i+1)]
|
|
1138
|
+
if trace == "":
|
|
1139
|
+
trace = elem
|
|
1140
|
+
elif trace[-2:] != elem:
|
|
1141
|
+
trace = f"{trace},{elem}"
|
|
1142
|
+
|
|
1143
|
+
logger.info(f"Trying {trace}")
|
|
1144
|
+
|
|
1145
|
+
await next_cmd(mc, ["trace", trace])
|
|
1146
|
+
|
|
1067
1147
|
async def next_cmd(mc, cmds, json_output=False):
|
|
1068
1148
|
""" process next command """
|
|
1069
1149
|
try :
|
|
@@ -1703,7 +1783,7 @@ async def next_cmd(mc, cmds, json_output=False):
|
|
|
1703
1783
|
print(res.payload)
|
|
1704
1784
|
print(json.dumps(res.payload, indent=4))
|
|
1705
1785
|
|
|
1706
|
-
case "trace" :
|
|
1786
|
+
case "trace" | "tr":
|
|
1707
1787
|
argnum = 1
|
|
1708
1788
|
res = await mc.commands.send_trace(path=cmds[1])
|
|
1709
1789
|
if res and res.type != EventType.ERROR:
|
|
@@ -1716,7 +1796,7 @@ async def next_cmd(mc, cmds, json_output=False):
|
|
|
1716
1796
|
if json_output:
|
|
1717
1797
|
print(json.dumps({"error" : "timeout waiting trace"}))
|
|
1718
1798
|
else :
|
|
1719
|
-
print("Timeout waiting trace")
|
|
1799
|
+
print(f"Timeout waiting trace for path {cmds[1]}")
|
|
1720
1800
|
elif ev.type == EventType.ERROR:
|
|
1721
1801
|
if json_output:
|
|
1722
1802
|
print(json.dumps(ev.payload))
|
|
@@ -1726,18 +1806,26 @@ async def next_cmd(mc, cmds, json_output=False):
|
|
|
1726
1806
|
if json_output:
|
|
1727
1807
|
print(json.dumps(ev.payload, indent=2))
|
|
1728
1808
|
else :
|
|
1809
|
+
classic = interactive_loop.classic or not process_event_message.color
|
|
1729
1810
|
print("]",end="")
|
|
1730
1811
|
for t in ev.payload["path"]:
|
|
1731
|
-
|
|
1812
|
+
if classic :
|
|
1813
|
+
print("→",end="")
|
|
1814
|
+
else:
|
|
1815
|
+
print(f" {ANSI_INVERT}", end="")
|
|
1732
1816
|
snr = t['snr']
|
|
1733
1817
|
if snr >= 10 :
|
|
1734
|
-
print(
|
|
1818
|
+
print(ANSI_BGREEN, end="")
|
|
1735
1819
|
elif snr <= 0:
|
|
1736
|
-
print(
|
|
1820
|
+
print(ANSI_BRED, end="")
|
|
1821
|
+
else :
|
|
1822
|
+
print(ANSI_BGRAY, end="")
|
|
1737
1823
|
print(f"{snr:.2f}",end="")
|
|
1738
|
-
if
|
|
1739
|
-
print(
|
|
1740
|
-
|
|
1824
|
+
if classic :
|
|
1825
|
+
print("→",end="")
|
|
1826
|
+
else :
|
|
1827
|
+
print(f"{ANSI_NORMAL}🭬",end="")
|
|
1828
|
+
print(ANSI_END, end="")
|
|
1741
1829
|
if "hash" in t:
|
|
1742
1830
|
print(f"[{t['hash']}]",end="")
|
|
1743
1831
|
else:
|
|
@@ -1840,26 +1928,19 @@ async def next_cmd(mc, cmds, json_output=False):
|
|
|
1840
1928
|
argnum = 1
|
|
1841
1929
|
await mc.ensure_contacts()
|
|
1842
1930
|
contact = mc.get_contact_by_name(cmds[1])
|
|
1843
|
-
res = await mc
|
|
1844
|
-
|
|
1845
|
-
if res.type == EventType.ERROR:
|
|
1931
|
+
res = await discover_path(mc, contact)
|
|
1932
|
+
if res is None:
|
|
1846
1933
|
print(f"Error while discovering path")
|
|
1847
1934
|
else:
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
print(json.dumps({"error" : "Timeout discovering path"}))
|
|
1854
|
-
else:
|
|
1855
|
-
print("Timeout discovering path")
|
|
1856
|
-
else :
|
|
1857
|
-
if json_output :
|
|
1858
|
-
print(json.dumps(res.payload, indent=4))
|
|
1935
|
+
if json_output :
|
|
1936
|
+
print(json.dumps(res, indent=4))
|
|
1937
|
+
else:
|
|
1938
|
+
if "error" in res :
|
|
1939
|
+
print("Timeout while discovering path")
|
|
1859
1940
|
else:
|
|
1860
|
-
outp = res
|
|
1941
|
+
outp = res['out_path']
|
|
1861
1942
|
outp = outp if outp != "" else "direct"
|
|
1862
|
-
inp = res
|
|
1943
|
+
inp = res['in_path']
|
|
1863
1944
|
inp = inp if inp != "" else "direct"
|
|
1864
1945
|
print(f"Path for {contact['adv_name']}: out {outp}, in {inp}")
|
|
1865
1946
|
|
|
@@ -2054,12 +2135,16 @@ async def next_cmd(mc, cmds, json_output=False):
|
|
|
2054
2135
|
else:
|
|
2055
2136
|
print(f"Unknown contact {cmds[1]}")
|
|
2056
2137
|
else:
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2138
|
+
path = cmds[2].replace(",","") # we'll accept path with ,
|
|
2139
|
+
try:
|
|
2140
|
+
res = await mc.commands.change_contact_path(contact, path)
|
|
2141
|
+
logger.debug(res)
|
|
2142
|
+
if res.type == EventType.ERROR:
|
|
2143
|
+
print(f"Error setting path: {res}")
|
|
2144
|
+
elif json_output :
|
|
2145
|
+
print(json.dumps(res.payload, indent=4))
|
|
2146
|
+
except ValueError:
|
|
2147
|
+
print(f"Bad path format {cmds[2]}")
|
|
2063
2148
|
|
|
2064
2149
|
case "change_flags" | "cf":
|
|
2065
2150
|
argnum = 2
|
|
@@ -2355,9 +2440,11 @@ async def process_script(mc, file, json_output=False):
|
|
|
2355
2440
|
lines=f.readlines()
|
|
2356
2441
|
|
|
2357
2442
|
for line in lines:
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2443
|
+
line = line.strip()
|
|
2444
|
+
if not (line == "" or line[0] == "#"):
|
|
2445
|
+
logger.debug(f"processing {line}")
|
|
2446
|
+
cmds = shlex.split(line)
|
|
2447
|
+
await process_cmds(mc, cmds, json_output)
|
|
2361
2448
|
|
|
2362
2449
|
def version():
|
|
2363
2450
|
print (f"meshcore-cli: command line interface to MeshCore companion radios {VERSION}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshcore-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.39
|
|
4
4
|
Summary: Command line interface to meshcore companion radios
|
|
5
5
|
Project-URL: Homepage, https://github.com/fdlamotte/meshcore-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/fdlamotte/meshcore-cli/issues
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
meshcore_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
meshcore_cli/__main__.py,sha256=PfYgibmu2LEtC-OV7L1UgmvV3swJ5rQ4bbXHlwUFlgE,83
|
|
3
|
+
meshcore_cli/meshcore_cli.py,sha256=z4m_c8BjC0W2tBovhFHFMO8JMQB4i8TlrU_sL4s6q-U,115459
|
|
4
|
+
meshcore_cli-1.1.39.dist-info/METADATA,sha256=zhtF7tz4od9NJEaak8G6HvLqeFH_uW2y-r5zLnh2EMM,11630
|
|
5
|
+
meshcore_cli-1.1.39.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
6
|
+
meshcore_cli-1.1.39.dist-info/entry_points.txt,sha256=77V29Pyth11GteDk7tneBN3MMk8JI7bTlS-BGSmxCmI,103
|
|
7
|
+
meshcore_cli-1.1.39.dist-info/licenses/LICENSE,sha256=F9s987VtS0AKxW7LdB2EkLMkrdeERI7ICdLJR60A9M4,1066
|
|
8
|
+
meshcore_cli-1.1.39.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
meshcore_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
meshcore_cli/__main__.py,sha256=PfYgibmu2LEtC-OV7L1UgmvV3swJ5rQ4bbXHlwUFlgE,83
|
|
3
|
-
meshcore_cli/meshcore_cli.py,sha256=5ydfiMoDCL5kKV2X8j3Sm-8qthjTMtLQjMswk8ZmXyU,112748
|
|
4
|
-
meshcore_cli-1.1.37.dist-info/METADATA,sha256=gLPMzBo0_pHHZPr5IQQL4xpkGl28nJIhxQmO6vvB8II,11630
|
|
5
|
-
meshcore_cli-1.1.37.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
6
|
-
meshcore_cli-1.1.37.dist-info/entry_points.txt,sha256=77V29Pyth11GteDk7tneBN3MMk8JI7bTlS-BGSmxCmI,103
|
|
7
|
-
meshcore_cli-1.1.37.dist-info/licenses/LICENSE,sha256=F9s987VtS0AKxW7LdB2EkLMkrdeERI7ICdLJR60A9M4,1066
|
|
8
|
-
meshcore_cli-1.1.37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|