add time range support
This commit is contained in:
parent
be7d32f7f2
commit
e3630699bd
2
app.json
2
app.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Sample node.js express app",
|
||||
"name": "beatsaber-metrics-tracker",
|
||||
"repository": "https://git.fascinated.cc/Fascinated/beatsaber-metrics-tracker",
|
||||
"healthchecks": {}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import express from "express";
|
||||
import { INFLUXDB_BUCKET, InfluxQueryAPI } from "../index";
|
||||
import { formatString } from "../utils/stringUtils";
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
// Query to get the player count history for tge last 24 hours in 1 hour intervals
|
||||
const getPlayerHistoryQuery = `from(bucket: "${INFLUXDB_BUCKET}")
|
||||
|> range(start: -24h)
|
||||
|> range(start: {})
|
||||
|> filter(fn: (r) => r["_measurement"] == "scoresaber")
|
||||
|> filter(fn: (r) => r["_field"] == "value")
|
||||
|> filter(fn: (r) => r["type"] == "player_count")
|
||||
@ -20,7 +21,18 @@ app.get("/", (req, res) => {
|
||||
|
||||
app.get("/analytics", async (req, res) => {
|
||||
const before = new Date().getTime();
|
||||
const rows = await InfluxQueryAPI.collectRows(getPlayerHistoryQuery);
|
||||
|
||||
const timeQuery = req.query.time || "24h";
|
||||
const timeInMs = parseTimeToMilliseconds(timeQuery.toString());
|
||||
if (timeInMs > 30 * 24 * 60 * 60 * 1000) {
|
||||
return res.status(400).json({
|
||||
error: "Time range too large. Max time range is 30 days.",
|
||||
});
|
||||
}
|
||||
|
||||
const rows = await InfluxQueryAPI.collectRows(
|
||||
formatString(getPlayerHistoryQuery, false, timeQuery)
|
||||
);
|
||||
let history = rows.map((row: any) => ({
|
||||
time: row._time,
|
||||
value: row._value !== null ? row._value.toFixed(0) : null,
|
||||
|
26
src/utils/stringUtils.ts
Normal file
26
src/utils/stringUtils.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Formats a string with the given arguments.
|
||||
*
|
||||
* @param str the string to check
|
||||
* @param uriEncodeStrings whether to uri encode the strings
|
||||
* @param args the arguments to replace
|
||||
* @returns the formatted string
|
||||
*/
|
||||
export function formatString(
|
||||
str: string,
|
||||
uriEncodeStrings: boolean,
|
||||
...args: any[]
|
||||
): string {
|
||||
return str.replace(/{}/g, (match) => {
|
||||
// If there are no arguments, return the match
|
||||
if (args.length === 0) {
|
||||
return match;
|
||||
}
|
||||
|
||||
// Otherwise, return the next argument
|
||||
if (uriEncodeStrings) {
|
||||
return encodeURIComponent(String(args.shift()));
|
||||
}
|
||||
return String(args.shift());
|
||||
});
|
||||
}
|
40
src/utils/timeUtils.ts
Normal file
40
src/utils/timeUtils.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Parses a time string to milliseconds.
|
||||
*
|
||||
* @param time the time to parse
|
||||
* @returns the time in milliseconds
|
||||
*/
|
||||
function parseTimeToMilliseconds(time: string) {
|
||||
// Regular expression to match the numeric value and unit
|
||||
const regex = /^(\d+)([smhdwMy])$/;
|
||||
|
||||
const match = time.match(regex);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(
|
||||
"Invalid time format. Example valid formats: 1s, 5m, 2h, 3d, 1w, 2M, 1y"
|
||||
);
|
||||
}
|
||||
|
||||
const value = parseInt(match[1]);
|
||||
const unit = match[2];
|
||||
|
||||
switch (unit) {
|
||||
case "s":
|
||||
return value * 1000; // seconds to milliseconds
|
||||
case "m":
|
||||
return value * 60 * 1000; // minutes to milliseconds
|
||||
case "h":
|
||||
return value * 60 * 60 * 1000; // hours to milliseconds
|
||||
case "d":
|
||||
return value * 24 * 60 * 60 * 1000; // days to milliseconds
|
||||
case "w":
|
||||
return value * 7 * 24 * 60 * 60 * 1000; // weeks to milliseconds
|
||||
case "M":
|
||||
return value * 30 * 24 * 60 * 60 * 1000; // months (approximate) to milliseconds
|
||||
case "y":
|
||||
return value * 365 * 24 * 60 * 60 * 1000; // years (approximate) to milliseconds
|
||||
default:
|
||||
throw new Error("Invalid time unit. Use one of: s, m, h, d, w, M, y");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user