fixing stuff after splitting jsons

This commit is contained in:
Davide Scaini
2026-04-09 15:27:00 +02:00
parent 8118f6f316
commit 084c652fdd
6 changed files with 315 additions and 17 deletions
+68 -7
View File
@@ -1,5 +1,5 @@
---
import { readFileSync } from 'node:fs';
import { readFileSync, readdirSync, existsSync } from 'node:fs';
import { join, resolve } from 'node:path';
import Base from '../../layouts/Base.astro';
import ActivityDetail from '../../components/ActivityDetail.svelte';
@@ -49,12 +49,73 @@ export async function getStaticPaths() {
const activities = readActivities(join(dataDir, 'index.json'));
const athlete = root.owner?.athlete ?? null;
return activities
.filter(a => a.privacy !== 'private' && a.id)
.map(a => ({
params: { id: a.id },
props: { activity: a, athlete },
}));
// Build the map from the index first
const byId = new Map(
activities
.filter(a => a.privacy !== 'private' && a.id)
.map(a => [a.id, { activity: a, athlete }])
);
// Fallback: scan _merged/activities/ directories for any JSON files not yet
// covered by the index (e.g. shard read failures, recently added activities).
try {
const userDirs = readdirSync(dataDir, { withFileTypes: true })
.filter(d => d.isDirectory() && !d.name.startsWith('_') && !d.name.startsWith('.'))
.map(d => d.name);
for (const handle of userDirs) {
// Prefer _merged, fall back to plain activities dir
const mergedActs = join(dataDir, handle, '_merged', 'activities');
const plainActs = join(dataDir, handle, 'activities');
const actsDir = existsSync(mergedActs) ? mergedActs : (existsSync(plainActs) ? plainActs : null);
if (!actsDir) continue;
const urlPrefix = existsSync(mergedActs)
? `${handle}/_merged/`
: `${handle}/`;
for (const file of readdirSync(actsDir)) {
if (!file.endsWith('.json') || file.endsWith('.timeseries.json')) continue;
const id = file.slice(0, -5); // strip .json
if (byId.has(id)) continue; // already covered by the index
try {
const detail = JSON.parse(readFileSync(join(actsDir, file), 'utf-8'));
if (detail.privacy === 'private') continue;
// Build a minimal ActivitySummary from the detail file
const a: ActivitySummary = {
id,
title: detail.title ?? id,
sport: detail.sport ?? 'other',
sub_sport: detail.sub_sport ?? null,
started_at: detail.started_at ?? '',
distance_m: detail.distance_m ?? null,
duration_s: detail.duration_s ?? null,
moving_time_s: detail.moving_time_s ?? null,
elevation_gain_m: detail.elevation_gain_m ?? null,
avg_speed_kmh: detail.avg_speed_kmh ?? null,
max_speed_kmh: detail.max_speed_kmh ?? null,
avg_hr_bpm: detail.avg_hr_bpm ?? null,
max_hr_bpm: detail.max_hr_bpm ?? null,
avg_cadence_rpm: detail.avg_cadence_rpm ?? null,
avg_power_w: detail.avg_power_w ?? null,
mmp: detail.mmp ?? null,
source: detail.source ?? null,
privacy: detail.privacy ?? 'public',
detail_url: `${urlPrefix}activities/${file}`,
track_url: detail.bbox ? `${urlPrefix}activities/${id}.geojson` : null,
preview_coords: null,
handle,
};
byId.set(id, { activity: a, athlete });
} catch { /* skip malformed files */ }
}
}
} catch { /* ignore scan errors */ }
return [...byId.values()].map(({ activity: a, athlete: ath }) => ({
params: { id: a.id },
props: { activity: a, athlete: ath },
}));
} catch {
return [];
}