server_photo_s85js/api_v1/scanner/processActivityFile.js
2026-08-11 08:45:04 +02:00

190 lines
5.7 KiB
JavaScript

// api_v1/scanner/processActivityFile.js
const path = require('path');
const fsp = require('fs/promises');
const { sha256 } = require('./utils');
const { log } = require('./logger');
const parseActivityFile = require('./parseActivityFile'); // 🔥 parser FIT/GPX/TCX
const loc = require('../geo.js');
const getElevation = require('./elevation');
const { WEB_ROOT, PATH_FULL } = require('../config');
// ---------------------------------------------------------
// processActivityFile → equivalente di processFile per le attività
// ---------------------------------------------------------
async function processActivityFile(userName, cartella, fileRelPath, absPath, ext, st) {
// 🔥 PARSING FIT/GPX/TCX
const parsed = await parseActivityFile(absPath);
// parsed contiene:
// {
// file_name,
// file_extension,
// format,
// display_name,
// route_name,
// title,
// description,
// notes,
// sport,
// activity_type,
// device_manufacturer,
// device_model,
// source_app,
// start_time_millis,
// end_time_millis,
// duration_millis,
// distance_meters,
// elevation_gain_meters,
// elevation_loss_meters,
// min_elevation_meters,
// max_elevation_meters,
// file_distance_meters,
// file_elevation_gain_meters,
// computed_distance_meters,
// computed_elevation_gain_meters,
// average_speed_mps,
// max_speed_mps,
// average_pace_sec_per_km,
// average_heart_rate,
// max_heart_rate,
// average_cadence,
// max_cadence,
// calories,
// power_avg,
// power_max,
// point_count,
// segment_count,
// lap_count,
// min_latitude,
// max_latitude,
// min_longitude,
// max_longitude,
// center_latitude,
// center_longitude,
// tags,
// diagnostics
// }
// ---------------------------------------------------------
// GPS → se manca altitudine, la calcoliamo
// ---------------------------------------------------------
let gps = null;
if (parsed.center_latitude != null && parsed.center_longitude != null) {
gps = {
lat: parsed.center_latitude,
lng: parsed.center_longitude,
alt: parsed.min_elevation_meters ?? null
};
if (gps.alt == null) {
gps.alt = await getElevation(gps.lat, gps.lng);
}
}
// ---------------------------------------------------------
// LOCATION → come per le foto
// ---------------------------------------------------------
const location = gps ? await loc(gps.lng, gps.lat) : null;
// ---------------------------------------------------------
// PATH FULL / RELATIVI
// ---------------------------------------------------------
const relPath = fileRelPath;
const fullPath = PATH_FULL
? path.posix.join('/activities', userName, cartella, fileRelPath)
: relPath;
// ---------------------------------------------------------
// ID deterministico
// ---------------------------------------------------------
const id = sha256(`${userName}/${cartella}/${fileRelPath}`);
// ---------------------------------------------------------
// COSTRUZIONE META (identico a normalizeActivity)
// ---------------------------------------------------------
return {
id,
user: userName,
cartella,
taken_at: new Date(parsed.start_time_millis).toISOString(),
file_name: parsed.file_name,
file_extension: parsed.file_extension,
format: parsed.format,
display_name: parsed.display_name,
route_name: parsed.route_name,
title: parsed.title,
description: parsed.description,
notes: parsed.notes,
sport: parsed.sport,
activity_type: parsed.activity_type,
device_manufacturer: parsed.device_manufacturer,
device_model: parsed.device_model,
source_app: parsed.source_app,
start_time_millis: parsed.start_time_millis,
end_time_millis: parsed.end_time_millis,
duration_millis: parsed.duration_millis,
distance_meters: parsed.distance_meters,
elevation_gain_meters: parsed.elevation_gain_meters,
elevation_loss_meters: parsed.elevation_loss_meters,
min_elevation_meters: parsed.min_elevation_meters,
max_elevation_meters: parsed.max_elevation_meters,
file_distance_meters: parsed.file_distance_meters,
file_elevation_gain_meters: parsed.file_elevation_gain_meters,
computed_distance_meters: parsed.computed_distance_meters,
computed_elevation_gain_meters: parsed.computed_elevation_gain_meters,
average_speed_mps: parsed.average_speed_mps,
max_speed_mps: parsed.max_speed_mps,
average_pace_sec_per_km: parsed.average_pace_sec_per_km,
average_heart_rate: parsed.average_heart_rate,
max_heart_rate: parsed.max_heart_rate,
average_cadence: parsed.average_cadence,
max_cadence: parsed.max_cadence,
calories: parsed.calories,
power_avg: parsed.power_avg,
power_max: parsed.power_max,
point_count: parsed.point_count,
segment_count: parsed.segment_count,
lap_count: parsed.lap_count,
min_latitude: parsed.min_latitude,
max_latitude: parsed.max_latitude,
min_longitude: parsed.min_longitude,
max_longitude: parsed.max_longitude,
center_latitude: parsed.center_latitude,
center_longitude: parsed.center_longitude,
size_bytes: st.size,
last_modified_millis: st.mtimeMs,
date_added_millis: Date.now(),
date_modified_millis: Date.now(),
last_scan_millis: Date.now(),
is_favorite: false,
is_hidden: false,
rating: 0,
tags: parsed.tags || [],
track_preview: parsed.track_preview || [],
scan_status: "ok",
scan_error: null,
diagnostics: parsed.diagnostics || null,
gps,
location,
path: fullPath
};
}
module.exports = processActivityFile;