refactor importing interfaces to use interface parser and allow importing all key value pairs
This commit is contained in:
105
meshchat.py
105
meshchat.py
@@ -593,6 +593,8 @@ class ReticulumMeshChat:
|
||||
@routes.get("/api/v1/reticulum/interfaces/export")
|
||||
async def export_interfaces(request):
|
||||
try:
|
||||
|
||||
# format interfaces for export
|
||||
output = []
|
||||
for interface_name, interface in self.reticulum.config["interfaces"].items():
|
||||
output.append(f"[[{interface_name}]]")
|
||||
@@ -607,8 +609,8 @@ class ReticulumMeshChat:
|
||||
"Content-Disposition": "attachment; filename=meshchat_interfaces"
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Export error: {str(e)}")
|
||||
return web.json_response({
|
||||
"message": f"Failed to export interfaces: {str(e)}"
|
||||
}, status=500)
|
||||
@@ -622,7 +624,7 @@ class ReticulumMeshChat:
|
||||
data = await request.json()
|
||||
config = data.get('config')
|
||||
|
||||
# parse config
|
||||
# parse interfaces from config
|
||||
interfaces = InterfaceConfigParser.parse(config)
|
||||
|
||||
return web.json_response({
|
||||
@@ -630,7 +632,6 @@ class ReticulumMeshChat:
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Preview error: {str(e)}")
|
||||
return web.json_response({
|
||||
"message": f"Failed to parse config file: {str(e)}"
|
||||
}, status=500)
|
||||
@@ -642,75 +643,47 @@ class ReticulumMeshChat:
|
||||
|
||||
# get request data
|
||||
data = await request.json()
|
||||
config_text = data.get('config')
|
||||
selected_interfaces = data.get('selected_interfaces')
|
||||
|
||||
print(f"Selected interfaces: {selected_interfaces}")
|
||||
current_interface = None
|
||||
config = data.get('config')
|
||||
selected_interface_names = data.get('selected_interface_names')
|
||||
|
||||
# parse interfaces from config
|
||||
interfaces = InterfaceConfigParser.parse(config)
|
||||
|
||||
# find selected interfaces
|
||||
selected_interfaces = []
|
||||
for interface in interfaces:
|
||||
if interface["name"] in selected_interface_names:
|
||||
selected_interfaces.append(interface)
|
||||
|
||||
# convert interfaces to object
|
||||
interface_config = {}
|
||||
|
||||
for line in config_text.splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if line.startswith("[[") and line.endswith("]]"):
|
||||
if current_interface and current_interface["name"] in selected_interfaces:
|
||||
name = current_interface["name"]
|
||||
interface_config[name] = {
|
||||
"type": current_interface.get("type"),
|
||||
"interface_enabled": "true",
|
||||
"target_host": current_interface.get("target_host"),
|
||||
"target_port": current_interface.get("target_port"),
|
||||
"listen_ip": current_interface.get("listen_ip"),
|
||||
"listen_port": current_interface.get("listen_port"),
|
||||
"forward_ip": current_interface.get("forward_ip"),
|
||||
"forward_port": current_interface.get("forward_port"),
|
||||
"port": current_interface.get("port"),
|
||||
"frequency": current_interface.get("frequency"),
|
||||
"bandwidth": current_interface.get("bandwidth"),
|
||||
"txpower": current_interface.get("txpower"),
|
||||
"spreadingfactor": current_interface.get("spreadingfactor"),
|
||||
"codingrate": current_interface.get("codingrate")
|
||||
}
|
||||
interface_config[name] = {k: v for k, v in interface_config[name].items() if v is not None}
|
||||
|
||||
name = line[2:-2]
|
||||
current_interface = {"name": name}
|
||||
elif current_interface is not None and "=" in line:
|
||||
key, value = [x.strip() for x in line.split("=", 1)]
|
||||
value = value.strip('"').strip("'")
|
||||
current_interface[key] = value
|
||||
|
||||
if current_interface and current_interface["name"] in selected_interfaces:
|
||||
name = current_interface["name"]
|
||||
interface_config[name] = {
|
||||
"type": current_interface.get("type"),
|
||||
"interface_enabled": "true",
|
||||
"target_host": current_interface.get("target_host"),
|
||||
"target_port": current_interface.get("target_port"),
|
||||
"listen_ip": current_interface.get("listen_ip"),
|
||||
"listen_port": current_interface.get("listen_port"),
|
||||
"forward_ip": current_interface.get("forward_ip"),
|
||||
"forward_port": current_interface.get("forward_port"),
|
||||
"port": current_interface.get("port"),
|
||||
"frequency": current_interface.get("frequency"),
|
||||
"bandwidth": current_interface.get("bandwidth"),
|
||||
"txpower": current_interface.get("txpower"),
|
||||
"spreadingfactor": current_interface.get("spreadingfactor"),
|
||||
"codingrate": current_interface.get("codingrate")
|
||||
}
|
||||
interface_config[name] = {k: v for k, v in interface_config[name].items() if v is not None}
|
||||
|
||||
for interface in selected_interfaces:
|
||||
|
||||
# add interface and keys/values
|
||||
interface_name = interface["name"]
|
||||
interface_config[interface_name] = {}
|
||||
for key, value in interface.items():
|
||||
interface_config[interface_name][key] = value
|
||||
|
||||
# unset name which isn't part of the config
|
||||
del interface_config[interface_name]["name"]
|
||||
|
||||
# force imported interface to be enabled by default
|
||||
interface_config[interface_name]["interface_enabled"] = "true"
|
||||
|
||||
# remove enabled config value in favour of interface_enabled
|
||||
if "enabled" in interface_config[interface_name]:
|
||||
del interface_config[interface_name]["enabled"]
|
||||
|
||||
# update reticulum config with new interfaces
|
||||
self.reticulum.config["interfaces"].update(interface_config)
|
||||
print("Final interfaces config:", self.reticulum.config["interfaces"])
|
||||
self.reticulum.config.write()
|
||||
return web.json_response({"message": "Interfaces imported successfully"})
|
||||
|
||||
return web.json_response({
|
||||
"message": "Interfaces imported successfully",
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Import error: {str(e)}")
|
||||
print(f"Config text: {config_text}")
|
||||
return web.json_response({
|
||||
"message": f"Failed to import interfaces: {str(e)}"
|
||||
}, status=500)
|
||||
|
||||
@@ -26,14 +26,21 @@ class InterfaceConfigParser:
|
||||
interface_name = line[2:-2]
|
||||
current_interface = {
|
||||
"name": interface_name,
|
||||
"type": None
|
||||
}
|
||||
|
||||
# we found a key=value line, so we will set these values on the interface
|
||||
elif current_interface is not None and "=" in line:
|
||||
|
||||
# parse key and value
|
||||
line_parts = line.split("=", 1)
|
||||
key = line_parts[0].strip()
|
||||
value = line_parts[1].strip()
|
||||
value = line_parts[1].strip().strip('"').strip("'")
|
||||
|
||||
# skip empty values or values equal to "None"
|
||||
if value is None or value == "None":
|
||||
continue
|
||||
|
||||
# set key/value on interface
|
||||
current_interface[key] = value
|
||||
|
||||
# add the final interface to the list
|
||||
|
||||
@@ -177,7 +177,7 @@ export default {
|
||||
// import interfaces
|
||||
await window.axios.post('/api/v1/reticulum/interfaces/import', {
|
||||
config: await this.selectedFile.text(),
|
||||
selected_interfaces: this.selectedInterfaces,
|
||||
selected_interface_names: this.selectedInterfaces,
|
||||
});
|
||||
|
||||
// dismiss modal
|
||||
|
||||
Reference in New Issue
Block a user