240 lines
4.8 KiB
JavaScript
240 lines
4.8 KiB
JavaScript
import readline from "readline";
|
|
import dotenv from "dotenv";
|
|
|
|
dotenv.config();
|
|
|
|
// ===============================
|
|
// CONFIG
|
|
// ===============================
|
|
const BASE_URL = process.env.BASE_URL;
|
|
|
|
if (!BASE_URL) {
|
|
console.error("ERRORE: BASE_URL non definita nel .env");
|
|
process.exit(1);
|
|
}
|
|
|
|
const WATCHER_TOKEN = process.env.WATCHER_TOKEN;
|
|
|
|
if (!WATCHER_TOKEN) {
|
|
console.error("ERRORE: WATCHER_TOKEN non definito nel .env");
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("Watcher globale avviato");
|
|
|
|
// ===============================
|
|
// STDIN
|
|
// ===============================
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
crlfDelay: Infinity
|
|
});
|
|
|
|
// ===============================
|
|
// ESTENSIONI FOTO/VIDEO
|
|
// ===============================
|
|
const photoExt = [
|
|
".jpg",
|
|
".jpeg",
|
|
".png",
|
|
".gif",
|
|
".bmp",
|
|
".webp",
|
|
".tiff",
|
|
".heic",
|
|
".heif",
|
|
".mp4",
|
|
".mov",
|
|
".avi",
|
|
".mkv",
|
|
".webm",
|
|
".m4v"
|
|
];
|
|
|
|
// ===============================
|
|
// ESTENSIONI ATTIVITÀ
|
|
// ===============================
|
|
const activityExt = [
|
|
".fit",
|
|
".gpx",
|
|
".tcx"
|
|
];
|
|
|
|
// ===============================
|
|
// PARSING PATH
|
|
// ===============================
|
|
function parsePath(fullPath) {
|
|
|
|
const match = fullPath.match(
|
|
/^\/app\/(photos|activities)\/([^/]+)\/original(?:\/|$)/
|
|
);
|
|
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
area: match[1],
|
|
user: match[2]
|
|
};
|
|
}
|
|
|
|
// ===============================
|
|
// FILTRO FILE
|
|
// ===============================
|
|
function isAllowedFile(area, filename) {
|
|
|
|
const lower = filename.toLowerCase();
|
|
|
|
if (area === "photos") {
|
|
return photoExt.some(ext => lower.endsWith(ext));
|
|
}
|
|
|
|
if (area === "activities") {
|
|
return activityExt.some(ext => lower.endsWith(ext));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// ===============================
|
|
// CHIAMATA API
|
|
// ===============================
|
|
async function callAutoScan(type, file, path, user) {
|
|
|
|
const relPath = path.replace(/^\/app/, "");
|
|
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${WATCHER_TOKEN}`
|
|
};
|
|
|
|
const payload = {
|
|
type,
|
|
file,
|
|
path: relPath,
|
|
user
|
|
};
|
|
|
|
console.log("AUTO_SCAN:", payload);
|
|
|
|
const res = await fetch(
|
|
`${BASE_URL}/api_v1/auto_scan`,
|
|
{
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify(payload)
|
|
}
|
|
);
|
|
|
|
if (!res.ok) {
|
|
console.error(
|
|
`Errore auto_scan ${res.status}`
|
|
);
|
|
}
|
|
|
|
return res.ok;
|
|
}
|
|
|
|
// ===============================
|
|
// WATCHER
|
|
// ===============================
|
|
function startWatcher() {
|
|
|
|
rl.on("line", async line => {
|
|
|
|
console.log("RAW:", line);
|
|
|
|
try {
|
|
|
|
const parts = line.trim().split(/\s+/);
|
|
|
|
if (parts.length < 3) {
|
|
console.log("EVENTO SCARTATO: formato non valido");
|
|
return;
|
|
}
|
|
|
|
const path = parts[0];
|
|
const action = parts[1];
|
|
const file = parts.slice(2).join(" ");
|
|
|
|
console.log({
|
|
path,
|
|
action,
|
|
file
|
|
});
|
|
|
|
const info = parsePath(path);
|
|
|
|
console.log("PARSE_PATH:", info);
|
|
|
|
if (!info) {
|
|
console.log("PATH IGNORATO");
|
|
return;
|
|
}
|
|
|
|
const { user, area } = info;
|
|
|
|
const isDir = action.includes("ISDIR");
|
|
|
|
if (!isDir && !isAllowedFile(area, file)) {
|
|
|
|
console.log(
|
|
`FILE IGNORATO area=${area} file=${file}`
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
let type = null;
|
|
|
|
if (action === "MOVED_TO,ISDIR") {
|
|
type = "ADD_DIR";
|
|
}
|
|
else if (action === "MOVED_FROM,ISDIR") {
|
|
type = "DEL_DIR";
|
|
}
|
|
else if (/^CLOSE_WRITE(,CLOSE)?$/.test(action)) {
|
|
type = "ADD";
|
|
}
|
|
else if (action === "MOVED_TO") {
|
|
type = "ADD";
|
|
}
|
|
else if (action === "MOVED_FROM") {
|
|
type = "DEL";
|
|
}
|
|
else if (action === "DELETE") {
|
|
type = "DEL";
|
|
}
|
|
else {
|
|
console.log(
|
|
`AZIONE IGNORATA: ${action}`
|
|
);
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
`[${area}] ${user} -> ${type} ${file}`
|
|
);
|
|
|
|
await callAutoScan(
|
|
type,
|
|
file,
|
|
path,
|
|
user
|
|
);
|
|
|
|
}
|
|
catch (err) {
|
|
|
|
console.error(
|
|
"Errore watcher:",
|
|
err
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
startWatcher();
|