server_photo_s85js/helpers/normalizeActivity.js
2026-08-11 08:45:04 +02:00

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;