mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-03-04 23:27:46 +01:00
Website configuration in config.ini
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -35,8 +35,8 @@
|
||||
</style>
|
||||
</head>
|
||||
<body hx-indicator="#spinner">
|
||||
<br><div style="text-align:center"><strong>{{ site_config.site_title }} - {{ site_config.site_domain }}</strong></div>
|
||||
<div style="text-align: center;">{{ site_config.site_message }}</div>
|
||||
<br><div style="text-align:center"><strong>{{ site_config["site"]["title"] }} - {{ site_config["site"]["domain"] }}</strong></div>
|
||||
<div style="text-align: center;">{{ site_config["site"]["message"] }}</div>
|
||||
<div style="text-align:center">Quick Links: <a href="/nodelist">Nodes</a> - <a href="/chat">Conversations</a> - <a href="/firehose">See <strong>everything</strong> </a>
|
||||
- Mesh Graph <a href="/nodegraph/LongFast">LF</a> - <a href="/nodegraph/MediumSlow">MS </a> - <a href="/stats">Stats </a>
|
||||
- <a href="/net">Weekly Net</a> - <a href="/map">Map</a> - <a href="/top">Top Traffic</a></div><br>
|
||||
|
||||
@@ -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
|
||||
|
||||
15
startdb.py
15
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(
|
||||
|
||||
Reference in New Issue
Block a user