@richhaase/c2 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/commands/report.ts +17 -9
- package/src/config.ts +1 -1
- package/src/index.ts +9 -0
- package/src/stats.ts +2 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ bun install -g @richhaase/c2
|
|
|
12
12
|
|
|
13
13
|
# Or install from source
|
|
14
14
|
git clone https://github.com/richhaase/c2.git
|
|
15
|
-
cd
|
|
15
|
+
cd c2
|
|
16
16
|
bun install
|
|
17
17
|
bun link
|
|
18
18
|
```
|
|
@@ -118,7 +118,7 @@ c2 export -f jsonl > workouts.jsonl
|
|
|
118
118
|
|
|
119
119
|
## Configuration
|
|
120
120
|
|
|
121
|
-
Config lives at `~/.config/
|
|
121
|
+
Config lives at `~/.config/c2/config.json`. Created automatically on `c2 setup`.
|
|
122
122
|
|
|
123
123
|
```json
|
|
124
124
|
{
|
package/package.json
CHANGED
package/src/commands/report.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { writeFile } from "node:fs/promises";
|
|
2
|
-
import {
|
|
1
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
3
4
|
import type { Command } from "commander";
|
|
4
5
|
import { loadConfig } from "../config.ts";
|
|
5
6
|
import { formatMeters } from "../display.ts";
|
|
@@ -651,7 +652,7 @@ ${buildRecentWorkouts(allWorkouts, recentCount)}
|
|
|
651
652
|
${buildProjection(goal, allWorkouts)}
|
|
652
653
|
|
|
653
654
|
<div style="text-align: center; color: #484f58; font-size: 12px; margin-top: 32px; padding-bottom: 16px;">
|
|
654
|
-
Generated by
|
|
655
|
+
Generated by c2 · Data from Concept2 Logbook · ${fullDate(today)}
|
|
655
656
|
</div>
|
|
656
657
|
|
|
657
658
|
</body>
|
|
@@ -661,11 +662,11 @@ ${buildProjection(goal, allWorkouts)}
|
|
|
661
662
|
export function registerReport(program: Command): void {
|
|
662
663
|
program
|
|
663
664
|
.command("report")
|
|
664
|
-
.description("Generate HTML progress report")
|
|
665
|
-
.option("-o, --output <file>", "
|
|
665
|
+
.description("Generate HTML progress report and open in browser")
|
|
666
|
+
.option("-o, --output <file>", "save to a specific file instead of a temp file")
|
|
666
667
|
.option("-w, --weeks <n>", "weeks of history to show", "12")
|
|
667
|
-
.option("--open", "open
|
|
668
|
-
.action(async (opts: { output
|
|
668
|
+
.option("--no-open", "don't open in browser")
|
|
669
|
+
.action(async (opts: { output?: string; weeks: string; open: boolean }) => {
|
|
669
670
|
const cfg = await loadConfig();
|
|
670
671
|
if (!cfg.goal.start_date || !cfg.goal.end_date) {
|
|
671
672
|
console.error("Goal dates not configured. Run `c2 setup` to set start and end dates.");
|
|
@@ -687,9 +688,14 @@ export function registerReport(program: Command): void {
|
|
|
687
688
|
const summaries = buildWeekSummaries(workouts, new Date(), weeks);
|
|
688
689
|
const html = buildHTML(goal, summaries, workouts, 10);
|
|
689
690
|
|
|
690
|
-
|
|
691
|
+
let outPath: string;
|
|
692
|
+
if (opts.output) {
|
|
693
|
+
outPath = resolve(opts.output);
|
|
694
|
+
} else {
|
|
695
|
+
const dir = await mkdtemp(join(tmpdir(), "c2-report-"));
|
|
696
|
+
outPath = join(dir, "report.html");
|
|
697
|
+
}
|
|
691
698
|
await writeFile(outPath, html, "utf-8");
|
|
692
|
-
console.log(`Report written to: ${outPath}`);
|
|
693
699
|
|
|
694
700
|
if (opts.open) {
|
|
695
701
|
const { spawn } = await import("node:child_process");
|
|
@@ -704,6 +710,8 @@ export function registerReport(program: Command): void {
|
|
|
704
710
|
console.error(`Could not open report: ${err.message}`);
|
|
705
711
|
});
|
|
706
712
|
child.unref();
|
|
713
|
+
} else {
|
|
714
|
+
console.log(`Report written to: ${outPath}`);
|
|
707
715
|
}
|
|
708
716
|
});
|
|
709
717
|
}
|
package/src/config.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -23,6 +23,15 @@ registerTrend(program);
|
|
|
23
23
|
registerExport(program);
|
|
24
24
|
registerReport(program);
|
|
25
25
|
|
|
26
|
+
// Default to `report` when run with no subcommand
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
const knownCommands = program.commands.map((c) => c.name());
|
|
29
|
+
const hasSubcommand = args.some((a) => knownCommands.includes(a));
|
|
30
|
+
const hasHelpOrVersion = args.some((a) => ["-h", "--help", "-v", "--version"].includes(a));
|
|
31
|
+
if (args.length === 0 || (!hasSubcommand && !hasHelpOrVersion)) {
|
|
32
|
+
process.argv.splice(2, 0, "report");
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
program.parseAsync(process.argv).catch((err: Error) => {
|
|
27
36
|
console.error(`Error: ${err.message}`);
|
|
28
37
|
process.exit(1);
|
package/src/stats.ts
CHANGED
|
@@ -71,7 +71,8 @@ export function buildWeekSummaries(workouts: Workout[], now: Date, weeks: number
|
|
|
71
71
|
if (t < cutoff || t > now) continue;
|
|
72
72
|
|
|
73
73
|
const monday = mondayOf(t);
|
|
74
|
-
const
|
|
74
|
+
const diffDays = Math.round((monday.getTime() - cutoff.getTime()) / (1000 * 60 * 60 * 24));
|
|
75
|
+
const idx = Math.floor(diffDays / 7);
|
|
75
76
|
if (idx < 0 || idx >= weeks) continue;
|
|
76
77
|
|
|
77
78
|
const ws = summaries[idx]!;
|