158 lines
4.2 KiB
JavaScript
158 lines
4.2 KiB
JavaScript
// helpers/normalizeActivity.js
|
|
|
|
function safeJsonParse(value, fallback) {
|
|
try {
|
|
return value ? JSON.parse(value) : fallback;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
function normalizeActivity(a) {
|
|
// ============================
|
|
// GPS compatibile con /photos
|
|
// ============================
|
|
const gps = (a.center_latitude != null && a.center_longitude != null)
|
|
? {
|
|
lat: a.center_latitude,
|
|
lng: a.center_longitude,
|
|
alt: a.min_elevation_meters ?? null
|
|
}
|
|
: null;
|
|
|
|
// ============================
|
|
// JSON fields
|
|
// ============================
|
|
const location = safeJsonParse(a.location, null);
|
|
const tags = safeJsonParse(a.tags, []);
|
|
const diagnostics = safeJsonParse(a.diagnostics, null);
|
|
|
|
// Preview percorso per thumbnails attività
|
|
const track_preview = safeJsonParse(a.track_preview, []);
|
|
|
|
// ============================
|
|
// Path stile /photos
|
|
// ============================
|
|
const path = `/activities/${a.user}/original/${a.cartella}/${a.file_name}`;
|
|
|
|
// ============================
|
|
// MIME type
|
|
// ============================
|
|
const mime_type = a.format || "application/octet-stream";
|
|
|
|
// ============================
|
|
// mtimeMs compatibile progressiveSync
|
|
// ============================
|
|
const mtimeMs =
|
|
a.last_modified_millis ??
|
|
a.date_modified_millis ??
|
|
a.date_added_millis ??
|
|
Date.now();
|
|
|
|
return {
|
|
// ============================
|
|
// Campi base come /photos
|
|
// ============================
|
|
id: a.id,
|
|
user: a.user,
|
|
cartella: a.cartella,
|
|
name: a.file_name,
|
|
path,
|
|
mime_type,
|
|
size_bytes: a.size_bytes,
|
|
mtimeMs,
|
|
|
|
taken_at: a.start_time_millis
|
|
? new Date(Number(a.start_time_millis)).toISOString()
|
|
: null,
|
|
|
|
data: a.start_time_millis
|
|
? new Date(Number(a.start_time_millis)).toISOString()
|
|
: null,
|
|
|
|
location,
|
|
gps,
|
|
|
|
// ============================
|
|
// Campi speciali delle activity
|
|
// ============================
|
|
file_name: a.file_name,
|
|
file_extension: a.file_extension,
|
|
format: a.format,
|
|
display_name: a.display_name,
|
|
route_name: a.route_name,
|
|
title: a.title,
|
|
description: a.description,
|
|
notes: a.notes,
|
|
sport: a.sport,
|
|
activity_type: a.activity_type,
|
|
device_manufacturer: a.device_manufacturer,
|
|
device_model: a.device_model,
|
|
source_app: a.source_app,
|
|
|
|
start_time_millis: a.start_time_millis,
|
|
end_time_millis: a.end_time_millis,
|
|
duration_millis: a.duration_millis,
|
|
|
|
distance_meters: a.distance_meters,
|
|
elevation_gain_meters: a.elevation_gain_meters,
|
|
elevation_loss_meters: a.elevation_loss_meters,
|
|
|
|
min_elevation_meters: a.min_elevation_meters,
|
|
max_elevation_meters: a.max_elevation_meters,
|
|
|
|
file_distance_meters: a.file_distance_meters,
|
|
file_elevation_gain_meters: a.file_elevation_gain_meters,
|
|
|
|
computed_distance_meters: a.computed_distance_meters,
|
|
computed_elevation_gain_meters: a.computed_elevation_gain_meters,
|
|
|
|
average_speed_mps: a.average_speed_mps,
|
|
max_speed_mps: a.max_speed_mps,
|
|
average_pace_sec_per_km: a.average_pace_sec_per_km,
|
|
|
|
average_heart_rate: a.average_heart_rate,
|
|
max_heart_rate: a.max_heart_rate,
|
|
average_cadence: a.average_cadence,
|
|
max_cadence: a.max_cadence,
|
|
|
|
calories: a.calories,
|
|
power_avg: a.power_avg,
|
|
power_max: a.power_max,
|
|
|
|
point_count: a.point_count,
|
|
segment_count: a.segment_count,
|
|
lap_count: a.lap_count,
|
|
|
|
min_latitude: a.min_latitude,
|
|
max_latitude: a.max_latitude,
|
|
min_longitude: a.min_longitude,
|
|
max_longitude: a.max_longitude,
|
|
center_latitude: a.center_latitude,
|
|
center_longitude: a.center_longitude,
|
|
|
|
last_modified_millis: a.last_modified_millis,
|
|
date_added_millis: a.date_added_millis,
|
|
date_modified_millis: a.date_modified_millis,
|
|
last_scan_millis: a.last_scan_millis,
|
|
|
|
is_favorite: !!a.is_favorite,
|
|
is_hidden: !!a.is_hidden,
|
|
rating: a.rating,
|
|
|
|
tags,
|
|
|
|
// Preview percorso per thumbnails FIT/GPX/TCX
|
|
track_preview,
|
|
|
|
scan_status: a.scan_status,
|
|
scan_error: a.scan_error,
|
|
|
|
// Importante per soft delete in gallery
|
|
deleted_at: a.deleted_at || null,
|
|
|
|
diagnostics
|
|
};
|
|
}
|
|
|
|
module.exports = normalizeActivity;
|