100 lines
2.9 KiB
D
100 lines
2.9 KiB
D
module report;
|
|
|
|
import utils;
|
|
import std.stdio;
|
|
import std.datetime;
|
|
import std.algorithm;
|
|
import std.array;
|
|
import d2sqlite3;
|
|
import data;
|
|
import std.json;
|
|
|
|
void makeReport(string[] sites) {
|
|
string[] sitesToReport = sites.length == 0 ? listAllOrigins() : sites;
|
|
if (sitesToReport.length == 0) {
|
|
writeln("No sites to report.");
|
|
return;
|
|
}
|
|
writeln("Creating report for " ~ createSiteNamesSummary(sitesToReport) ~ ".");
|
|
foreach (site; sitesToReport) {
|
|
writeln("Site: " ~ site);
|
|
SiteReport report = generateReport(site, Clock.currTime(UTC()) - hours(48), Clock.currTime(UTC()));
|
|
writeln(report.toJson().toPrettyString());
|
|
}
|
|
}
|
|
|
|
string createSiteNamesSummary(string[] sites) {
|
|
if (sites.length == 0) return "all sites";
|
|
if (sites.length == 1) return "site " ~ sites[0];
|
|
import std.array;
|
|
auto app = appender!string();
|
|
app ~= "sites ";
|
|
foreach (i, site; sites) {
|
|
app ~= site;
|
|
if (i + 2 == sites.length) {
|
|
app ~= ", and ";
|
|
} else if (i + 1 < sites.length) {
|
|
app ~= ", ";
|
|
}
|
|
}
|
|
return app[];
|
|
}
|
|
|
|
struct SiteReport {
|
|
string siteName;
|
|
SysTime periodStart;
|
|
SysTime periodEnd;
|
|
|
|
ulong totalSessions;
|
|
double meanSessionDurationSeconds;
|
|
double meanEventsPerSession;
|
|
|
|
JSONValue toJson() const {
|
|
JSONValue obj = JSONValue(string[string].init);
|
|
obj.object["siteName"] = siteName;
|
|
obj.object["periodStart"] = periodStart.toISOExtString();
|
|
obj.object["periodEnd"] = periodEnd.toISOExtString();
|
|
obj.object["totalSessions"] = totalSessions;
|
|
obj.object["meanSessionDurationSeconds"] = meanSessionDurationSeconds;
|
|
obj.object["meanEventsPerSession"] = meanEventsPerSession;
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
SiteReport generateReport(string site, SysTime periodStart, SysTime periodEnd) {
|
|
SiteReport report;
|
|
report.siteName = site;
|
|
report.periodStart = periodStart;
|
|
report.periodEnd = periodEnd;
|
|
immutable string TS_START = formatSqliteTimestamp(periodStart);
|
|
immutable string TS_END = formatSqliteTimestamp(periodEnd);
|
|
writefln!"TS_START = %s, TS_END = %s"(TS_START, TS_END);
|
|
Database db = getOrCreateDatabase(site);
|
|
|
|
report.totalSessions = db.execute(q"SQL
|
|
SELECT COUNT(id)
|
|
FROM session
|
|
WHERE start_timestamp >= ? AND end_timestamp <= ?
|
|
SQL",
|
|
TS_START, TS_END
|
|
).oneValue!ulong();
|
|
|
|
report.meanEventsPerSession = db.execute(q"SQL
|
|
SELECT AVG(event_count)
|
|
FROM session
|
|
WHERE start_timestamp >= ? AND end_timestamp <= ?
|
|
SQL",
|
|
TS_START, TS_END
|
|
).oneValue!double();
|
|
|
|
report.meanSessionDurationSeconds = db.execute(q"SQL
|
|
SELECT AVG((julianday(end_timestamp) - julianday(start_timestamp)) * 24 * 60 * 60)
|
|
FROM session
|
|
WHERE start_timestamp >= ? AND end_timestamp <= ?
|
|
SQL",
|
|
TS_START, TS_END
|
|
).oneValue!double();
|
|
|
|
return report;
|
|
}
|