diff --git a/meshview/config.py b/meshview/config.py
index 4bc5ff1..17e1923 100644
--- a/meshview/config.py
+++ b/meshview/config.py
@@ -7,25 +7,9 @@ parser.add_argument("--config", type=str, default="config.ini", help="Path to co
args = parser.parse_args()
# Initialize config parser
-config = configparser.ConfigParser()
-if not config.read(args.config):
+config_parser = configparser.ConfigParser()
+if not config_parser.read(args.config):
raise FileNotFoundError(f"Config file '{args.config}' not found! Ensure the file exists.")
-# MQTT settings
-SERVER = config["MQTT"].get("SERVER", "localhost")
-TOPICS = config["MQTT"].get("TOPICS", "").split(",") # Convert to list
-MQTT_PORT = int(config["MQTT"].get("PORT", 1883))
-USERNAME = config["MQTT"].get("USERNAME", "")
-PASSWORD = config["MQTT"].get("PASSWORD", "")
+CONFIG = {section: dict(config_parser.items(section)) for section in config_parser.sections()}
-# Database settings
-CONNECTION_STRING = config["DATABASE"].get("CONNECTION_STRING", "sqlite:///meshview.db")
-
-# Server settings
-BIND = config["SERVER"].get("BIND", "0.0.0.0")
-WEB_PORT = int(config["SERVER"].get("PORT", 8080))
-TLS_CERTS = config["SERVER"].get("TLS_CERTS", "")
-ACME_CHALLENGE = config["SERVER"].get("ACME_CHALLENGE", "")
-
-# Website settings
-TITLE = config["WEBSITE"].get("TITLE", "MeshView")
diff --git a/meshview/models.py b/meshview/models.py
index 752c102..5e76914 100644
--- a/meshview/models.py
+++ b/meshview/models.py
@@ -33,7 +33,7 @@ class Packet(Base):
)
to_node_id: Mapped[int] = mapped_column(BigInteger,nullable=True)
to_node: Mapped["Node"] = relationship(
- primaryjoin="Packet.to_node_id == foreign(Node.node_id)", lazy="joined"
+ primaryjoin="Packet.to_node_id == foreign(Node.node_id)", lazy="joined", overlaps="from_node"
)
payload: Mapped[bytes] = mapped_column(nullable=True)
import_time: Mapped[datetime] = mapped_column(nullable=True)
@@ -45,7 +45,7 @@ class PacketSeen(Base):
packet_id = mapped_column(ForeignKey("packet.id"), primary_key=True)
node_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
node: Mapped["Node"] = relationship(
- lazy="joined", primaryjoin="PacketSeen.node_id == foreign(Node.node_id)"
+ lazy="joined", primaryjoin="PacketSeen.node_id == foreign(Node.node_id)", overlaps="from_node,to_node"
)
rx_time: Mapped[int] = mapped_column(BigInteger, primary_key=True)
hop_limit: Mapped[int] = mapped_column(nullable=True)
@@ -68,10 +68,3 @@ class Traceroute(Base):
done: Mapped[bool] = mapped_column(nullable=True)
route: Mapped[bytes] = mapped_column(nullable=True)
import_time: Mapped[datetime] = mapped_column(nullable=True)
-
-class SiteConfig(Base):
- __tablename__="site_config"
- id: Mapped[int] = mapped_column(primary_key=True)
- site_domain: Mapped[str] = mapped_column(nullable=False)
- site_title: Mapped[str] = mapped_column(nullable=False)
- site_message: Mapped[str] = mapped_column(nullable=True)
diff --git a/meshview/store.py b/meshview/store.py
index d23f47c..14b5aa0 100644
--- a/meshview/store.py
+++ b/meshview/store.py
@@ -2,7 +2,7 @@ import datetime
from sqlalchemy import select, func
from sqlalchemy.orm import lazyload
from meshview import database
-from meshview.models import Packet, PacketSeen, Node, Traceroute, SiteConfig
+from meshview.models import Packet, PacketSeen, Node, Traceroute
from sqlalchemy import text
@@ -312,12 +312,3 @@ async def get_nodes(role=None, channel=None, hw_model=None):
except Exception as e:
print("error reading DB") # Consider using logging instead of print
return [] # Return an empty list in case of failure
-
-
-async def get_site_config():
- async with database.async_session() as session:
- query = select(SiteConfig)
- result = await session.execute(query)
- #print(result.scalar())
- site_config = result.scalars().all()[-1]
- return site_config
\ No newline at end of file
diff --git a/meshview/templates/base.html b/meshview/templates/base.html
index 0908770..e1eb645 100644
--- a/meshview/templates/base.html
+++ b/meshview/templates/base.html
@@ -35,8 +35,8 @@
-
{{ site_config.site_title }} - {{ site_config.site_domain }}
- {{ site_config.site_message }}
+
{{ site_config["site"]["title"] }} - {{ site_config["site"]["domain"] }}
+ {{ site_config["site"]["message"] }}
diff --git a/meshview/web.py b/meshview/web.py
index 51fe51c..be8fbf5 100644
--- a/meshview/web.py
+++ b/meshview/web.py
@@ -24,10 +24,13 @@ from meshview import database
import psutil
import gc
from meshview import config
+import json
+
+CONFIG = config.CONFIG
env = Environment(loader=PackageLoader("meshview"), autoescape=select_autoescape())
# Start Database
-database.init_database(config.CONNECTION_STRING)
+database.init_database(CONFIG["database"]["connection_string"])
# Optimize garbage collection frequency
gc.set_threshold(100, 10, 10)
@@ -254,7 +257,7 @@ async def node_match(request):
return web.Response(
text=template.render(
node_options=node_options,
- site_config = await store.get_site_config()
+ site_config = CONFIG
),
content_type="text/html",
@@ -290,7 +293,7 @@ async def packet_list(request):
neighbors=neighbors,
has_telemetry=await has_telemetry,
query_string=request.query_string,
- site_config = await store.get_site_config(),
+ site_config = CONFIG,
),
content_type="text/html",
)
@@ -346,7 +349,7 @@ async def packet_details(request):
from_node_cord=from_node_cord,
uplinked_nodes=uplinked_nodes,
node=node,
- site_config = await store.get_site_config(),
+ site_config = CONFIG,
),
content_type="text/html",
)
@@ -364,7 +367,7 @@ async def packet_details(request):
text=template.render(
packets=(Packet.from_model(p) for p in packets),
portnum=portnum,
- site_config = await store.get_site_config(),
+ site_config = CONFIG,
),
content_type="text/html",
)
@@ -381,7 +384,7 @@ async def packet(request):
template = env.get_template("packet_index.html")
return web.Response(
- text=template.render(packet=Packet.from_model(packet), site_config = await store.get_site_config()),
+ text=template.render(packet=Packet.from_model(packet), site_config = CONFIG),
content_type="text/html",
)
@@ -1079,7 +1082,7 @@ async def nodelist(request):
template = env.get_template("nodelist.html")
print_memory_usage()
return web.Response(
- text=template.render(nodes=nodes, site_config = await store.get_site_config()),
+ text=template.render(nodes=nodes, site_config = CONFIG),
content_type="text/html",
)
except Exception as e:
@@ -1115,7 +1118,7 @@ async def net(request):
# Render template
template = env.get_template("net.html")
return web.Response(
- text=template.render(packets=filtered_packets, site_config = await store.get_site_config()),
+ text=template.render(packets=filtered_packets, site_config = CONFIG),
content_type="text/html",
)
@@ -1138,7 +1141,7 @@ async def map(request):
template = env.get_template("map.html")
print_memory_usage()
return web.Response(
- text=template.render(nodes=nodes, site_config = await store.get_site_config()),
+ text=template.render(nodes=nodes, site_config = CONFIG),
content_type="text/html",
)
except Exception as e:
@@ -1172,7 +1175,7 @@ async def stats(request):
total_packets_seen=total_packets_seen,
total_nodes_longfast=total_nodes_longfast,
total_nodes_mediumslow=total_nodes_mediumslow,
- site_config = await store.get_site_config(),
+ site_config = CONFIG,
),
content_type="text/html",
)
@@ -1193,12 +1196,12 @@ async def top(request):
node_traffic = await store.get_node_traffic(int(node_id))
print(node_traffic)
template = env.get_template("node_traffic.html") # Render a different template
- html_content = template.render(traffic=node_traffic, node_id=node_id, site_config = await store.get_site_config())
+ html_content = template.render(traffic=node_traffic, node_id=node_id, site_config = CONFIG)
else:
# Otherwise, fetch top traffic nodes as usual
top_nodes = await store.get_top_traffic_nodes()
template = env.get_template("top.html")
- html_content = template.render(nodes=top_nodes, site_config = await store.get_site_config())
+ html_content = template.render(nodes=top_nodes, site_config = CONFIG)
return web.Response(
text=html_content,
@@ -1236,7 +1239,7 @@ async def chat(request):
#print("Rendering template...")
template = env.get_template("chat.html")
return web.Response(
- text=template.render(packets=filtered_packets, site_config = await store.get_site_config()),
+ text=template.render(packets=filtered_packets, site_config = CONFIG),
content_type="text/html",
)
@@ -1326,7 +1329,7 @@ async def nodegraph(request):
text=template.render(
nodes=nodes_with_edges,
edges=edges, # Pass edges with color info
- site_config = await store.get_site_config(),
+ site_config = CONFIG,
),
content_type="text/html",
)
@@ -1336,8 +1339,10 @@ async def nodegraph(request):
@routes.get("/config")
async def get_config(request):
return web.json_response({
- "Server": config.SERVER,
- "Title": config.TITLE
+ "Server": CONFIG["site"]["domain"],
+ "Title": CONFIG["site"]["title"],
+ "Message": CONFIG["site"]["message"],
+ "Topics": json.loads(CONFIG["mqtt"]["topics"])
})
@@ -1346,13 +1351,13 @@ async def run_server():
app.add_routes(routes)
runner = web.AppRunner(app)
await runner.setup()
- if config.TLS_CERTS:
+ if CONFIG["server"]["tls_cert"]:
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
- ssl_context.load_cert_chain(config.TLS_CERTS)
+ ssl_context.load_cert_chain(CONFIG["server"]["tls_cert"])
else:
ssl_context = None
- for host in config.BIND:
- site = web.TCPSite(runner, host, config.WEB_PORT, ssl_context=ssl_context)
+ for host in CONFIG["server"]["bind"]:
+ site = web.TCPSite(runner, host, CONFIG["server"]["port"], ssl_context=ssl_context)
await site.start()
while True:
await asyncio.sleep(3600) # sleep forever
diff --git a/startdb.py b/startdb.py
index e8507c4..df39451 100644
--- a/startdb.py
+++ b/startdb.py
@@ -4,7 +4,6 @@ import configparser
from meshview import mqtt_reader
from meshview import mqtt_database
from meshview import mqtt_store
-from meshview import models
import json
@@ -24,19 +23,7 @@ async def main(config):
if config["mqtt"]["password"] != "":
mqtt_passwd: str = config["mqtt"]["password"]
mqtt_topics = json.loads(config["mqtt"]["topics"])
-
- # Create database with site configuration
- async with mqtt_database.async_session() as session:
- print(config["site"]["domain"])
- site_config = models.SiteConfig(
- site_domain = config["site"]["domain"],
- site_title = config["site"]["title"],
- site_message = config["site"]["message"]
- )
-
- session.add(site_config)
- await session.commit()
- # print("Site configuration loaded to database")
+
async with asyncio.TaskGroup() as tg:
tg.create_task(