sitestat/source/report.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;
}