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"] }}
Quick Links:  Nodes - Conversations - See everything  - Mesh Graph LF - MS  - Stats  - Weekly Net - Map - Top Traffic

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(