// 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;