Extend run stats DSL with statistical and temporal analysis
This commit is contained in:
+14
-6
@@ -26,7 +26,8 @@ class QueryError(ValueError):
|
||||
self.line = line
|
||||
|
||||
|
||||
def parse_dsl(text, metrics, defaults):
|
||||
def parse_dsl(text, metrics, defaults, units=None):
|
||||
units = units or UNITS
|
||||
if not isinstance(text, str) or len(text) > 4000:
|
||||
raise QueryError("Keep the query under 4,000 characters.")
|
||||
q = dict(defaults)
|
||||
@@ -52,8 +53,8 @@ def parse_dsl(text, metrics, defaults):
|
||||
raise QueryError(f"Unknown metric '{key}'.{hint}", line)
|
||||
|
||||
def amount(key, raw, unit, line):
|
||||
if unit not in UNITS[key]:
|
||||
raise QueryError(f"Use {' or '.join(UNITS[key])} for {key}.", line)
|
||||
if unit not in units[key]:
|
||||
raise QueryError(f"Use {' or '.join(units[key])} for {key}.", line)
|
||||
if key == "pace" and ":" in raw:
|
||||
minutes, seconds = raw.split(":")
|
||||
if not minutes.isdecimal() or not seconds.isdecimal() or int(seconds) >= 60:
|
||||
@@ -64,9 +65,16 @@ def parse_dsl(text, metrics, defaults):
|
||||
value = float(raw)
|
||||
except ValueError:
|
||||
raise QueryError("Use a numeric value with its unit.", line) from None
|
||||
if not math.isfinite(value) or not 0 <= value <= 1000000:
|
||||
raise QueryError("Filter values must be finite and between 0 and 1,000,000.", line)
|
||||
return value * UNITS[key][unit]
|
||||
if not math.isfinite(value) or not -1000000 <= value <= 1000000:
|
||||
raise QueryError(
|
||||
"Filter values must be finite and between -1,000,000 and 1,000,000.", line
|
||||
)
|
||||
if (
|
||||
key in {"distance", "heart_rate", "analysis_raw_distance", "analysis_raw_heart_rate"}
|
||||
and value < 0
|
||||
):
|
||||
raise QueryError("Distance and heart rate cannot be negative.", line)
|
||||
return value * units[key][unit]
|
||||
|
||||
def condition(key, op, value, line):
|
||||
legacy = {
|
||||
|
||||
Reference in New Issue
Block a user