1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92import { DatabaseSync } from 'node:sqlite'
import { exit } from 'node:process'
import { parseArgs } from 'jsr:@std/cli/parse-args'
import {
dataFsPie,
musicFsPie,
numInstanceLine,
osPie,
playerTypePie,
} from './generators.ts'
const flags = parseArgs(Deno.args, {
string: ['db-path', 'output-dir'],
boolean: ['help', 'verbose'],
default: {
'db-path': Deno.env.get('INSIGHT_DB_PATH'),
'output-dir': Deno.env.get('INSIGHT_OUTPUT_DIR') ?? '.',
'verbose': ["1", "true", "yes"].includes(
(Deno.env.get("INSIGHT_VERBOSE") ?? "").toLowerCase()),
},
alias: { d: 'db-path', o: 'output-dir', v: 'verbose' },
})
const log = flags['verbose']
? (...args: unknown[]) => {
const now = new Date()
const timestamp = now.toISOString()
.replace(/T/, ' ')
.replace(/\..+/, '')
.replace(/-/g, '/')
console.log(`${timestamp}`, ...args)
}
: console.log
flags['output-dir'] = flags['output-dir'].replace(/\/$/, '')
const printUsage = () =>
console.log(
`Usage: insight-charts [options]
Options:
-d, --db-path <path> Path to the SQLite database (required)
-o, --output-dir <path> Output directory for visualization files (default: '.')
-v, --verbose Add date and time to log messages
--help Display this help message
Environment variables (override the matching options):
INSIGHT_DB_PATH Same as --db-path
INSIGHT_OUTPUT_DIR Same as --output-dir
INSIGHT_VERBOSE Same as --verbose
Example:
insight-charts -d ./db/insights.db -o ./visualizations`,
)
if (flags.help) {
printUsage()
exit(0)
}
if (flags['db-path'] === undefined) {
console.log('insight-charts: Database path must be specified')
exit(1)
}
log('Opening SQLite database at:', flags['db-path'])
const db = new DatabaseSync(flags['db-path'])
const summaryStmt = db.prepare('select data from summary order by time desc')
const timeSeriesStmt = db.prepare(
"select time, data from summary where data not like '{}' and time > '2024-12-21' and time < (select max(time) from summary)",
)
Deno.mkdir(flags['output-dir'], { recursive: true }).catch(() => {})
const charts = [
{ filename: 'osPie.json', generator: osPie, stmt: summaryStmt },
{ filename: 'musicFsPie.json', generator: musicFsPie, stmt: summaryStmt },
{ filename: 'dataFsPie.json', generator: dataFsPie, stmt: summaryStmt },
{ filename: 'playerTypePie.json', generator: playerTypePie, stmt: summaryStmt },
{ filename: 'numInstance.json', generator: numInstanceLine, stmt: timeSeriesStmt },
]
for (const { filename, generator, stmt } of charts) {
const path = `${flags['output-dir']}/${filename}`
log(`Saving ${path}`)
await Deno.writeTextFile(path, generator(stmt))
}
log('All charts saved, bye bye!')
db.close()