From 2ca618eedd9149e1aa3085c9ae986718301c5eec Mon Sep 17 00:00:00 2001 From: "Peter J. Holzer" Date: Sun, 20 Oct 2024 11:27:23 +0200 Subject: [PATCH] Add navigation --- app.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index e4dae99..f5b3c6e 100644 --- a/app.py +++ b/app.py @@ -5,7 +5,9 @@ import logging import logging.config import os -from flask import (Flask, request, jsonify, abort, render_template) +from collections import defaultdict + +from flask import (Flask, request, jsonify, abort, render_template, url_for) from ltsdb_json import LTS from dashboard import Dashboard @@ -152,3 +154,71 @@ def dashboard_index(): def dashboard_file(dashboard): d = Dashboard("dashboards/" + dashboard + ".json") return d.as_html() + +@app.get("/nav") +def nav(): + # Start with a list of all dimensions, the number of matching time series + # and a truncated list of series. + # If a dimension is chosen, display a choice of members + # choosing one or more members goes back to the list of + # (remaining) dimensions + with open("data/.index") as fh: + fcntl.flock(fh, fcntl.LOCK_SH) + index = json.load(fh) + timeseries = None + for k, v in request.args.lists(): + if k[0] == ".": + continue + log.debug("search: %s -> %s", k, v) + if timeseries is None: + timeseries = set() + log.debug("search: %s: %s", k, index[k]) + for m in v: + timeseries |= set(index[k][m]) + else: + filter = set() + for m in v: + filter |= set(index[k][m]) + timeseries &= filter + if timeseries is None: + timeseries = set() + for mc in index.values(): + for tsl in mc.values(): + timeseries |= set(tsl) + if d := request.args.get(".m"): + members = [] + for m, tsl in index[d].items(): + if set(tsl) & timeseries: + members.append(m) + return render_template("nav_member_select.html", dimension=d, members=members) + else: + params = request.args.to_dict(flat=False) + matching_dimensions = defaultdict(int) + for d, mc in index.items(): + if d in params: + continue + for m, tsl in mc.items(): + mtsl = set(tsl) & timeseries + if mtsl: + matching_dimensions[d] += len(mtsl) + matching_dimensions_list = [] + for d in matching_dimensions: + params[".m"] = d + url = url_for("nav", **params) + app.logger.debug(f"{d=} {url=}") + matching_dimensions_list.append( + {"name": d, "count": matching_dimensions[d], "url": url} + ) + total_timeseries = len(timeseries) + timeseries = [LTS(id=ts) for ts in list(timeseries)[:100]] + return render_template( + "nav_dimension_list.html", + matching_dimensions=matching_dimensions_list, + timeseries=timeseries, total_timeseries=total_timeseries) + + + + + + + #