Log_service/app/Controllers/Http/ErpsController.ts

286 lines
8.2 KiB
TypeScript

import fs from "fs";
import type { HttpContextContract } from "@ioc:Adonis/Core/HttpContext";
import axios from "axios";
import Env from "@ioc:Adonis/Core/Env";
const path = require("path");
const BASE_URL = Env.get("BASE_URL_LOG");
const BASE_URL_AUTO = `${BASE_URL}/AUTOlog/`;
export default class ErpsController {
/**
* Controller do tim cac serial number trong cac log trong khoang thoi gian xac dinh
* @param {Integer} from thoi gian bat dau YYYYMMDD (vd: 20230130)
* @param {Integer} to thoi gian ket thuc YYYYMMDD (vd: 20230230)
*/
public async getIndexSerialNumber({
request,
response,
}: HttpContextContract) {
const { from, to } = request.all();
const getListLog = async (from, to) => {
try {
const listLog: string[] = [];
const response = await axios.get(BASE_URL);
// const responseAUTO = await axios.get(BASE_URL_AUTO);
console.log("check!!!!!!!!!!!!!!!!!!!!!")
let data1 = response.data
.split("\n")
.filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);
// let data2 = responseAUTO.data
// .split("\n")
// .filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);
const arrayLine = data1;
// const arrayLineAUTO = data
// .split("\n")
// .filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);
arrayLine.map((u) => {
let temp = u
.slice(u.search("<a ") + 9, u.search("</a>"))
.split(">")[1];
if (
parseInt(temp?.split("-")[0]) >= from &&
parseInt(temp?.split("-")[0]) <= to
) {
listLog.push(
(BASE_URL + "/") +
u.slice(u.search("<a ") + 9, u.search("</a>")).split(">")[1] +
" "
);
}
});
return listLog;
} catch (error) {
console.log(error);
}
};
const fetchWithRetry = async (url) => {
let retries = 0;
const MAX_RETRIES = 10;
while (retries < MAX_RETRIES) {
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
if (error.code) {
retries++;
continue;
} else {
console.error("Error fetching file:", error);
return null;
}
}
}
return null;
};
const extractInfoFromLine = (line, index, fName) => {
const cleanedLine = line.replace(/\r/g, "");
const results: any = [];
const getWarehouse = (fileName) =>
/(US(?!A)|-US|\.US|US-)/.test(fileName) ? "US" : "AU";
const extractSN = (str) =>
str?.replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "").trim();
// PID & SN
if (
cleanedLine.includes("PID:") &&
cleanedLine.includes("SN:") &&
!cleanedLine.includes("%")
) {
const parts = cleanedLine.split(",");
const SN = extractSN(
parts.find((p) => p.includes("SN:"))?.split(":")[1] ?? ""
);
const PID = extractSN(
parts.find((p) => p.includes("PID:"))?.split(":")[1] ?? ""
);
const VID = extractSN(
parts.find((p) => p.includes("VID:"))?.split(":")[1] ?? ""
);
if (SN && SN !== "N/A" && SN.length > 4) {
results.push({
PID,
VID,
SN,
line: [index + 1],
fileName: fName,
warehouse: getWarehouse(fName),
});
}
}
// Serial Number
if (cleanedLine.includes("Serial Number")) {
const PCB_SN = extractSN(cleanedLine.split(":")[1]);
if (PCB_SN) {
results.push({
PID: "",
VID: "",
SN: PCB_SN,
line: [index + 1],
fileName: fName,
warehouse: getWarehouse(fName),
});
}
}
// Vendor Serial (SN)
if (cleanedLine.includes("Vendor Serial (SN)")) {
const PCB_SN = extractSN(cleanedLine.split(":")[1]);
if (PCB_SN) {
results.push({
PID: "",
VID: "",
SN: PCB_SN.trim(),
line: [index + 1],
fileName: fName,
warehouse: getWarehouse(fName),
});
}
}
if (cleanedLine.includes("System serial num")) {
const PCB_SN = extractSN(cleanedLine.split(":")[1]);
if (PCB_SN) {
results.push({
PID: "",
VID: "",
SN: PCB_SN,
line: [index + 1],
fileName: fName,
warehouse: getWarehouse(fName),
});
}
}
// Processor board ID
if (cleanedLine.includes("Processor board ID")) {
const PBID = extractSN(cleanedLine.split(" ").pop());
if (PBID?.length >= 8) {
results.push({
PID: "",
VID: "",
SN: PBID,
line: [index + 1],
fileName: fName,
warehouse: getWarehouse(fName),
});
}
}
return results;
};
const mergeLines = (output, lineResult) => {
lineResult.forEach((entry) => {
const existing = output.find((o) => o.SN === entry.SN);
if (existing) {
existing.line = [...new Set([...existing.line, ...entry.line])];
if (entry.PID) existing.PID = entry.PID;
if (entry.VID) existing.VID = entry.VID;
} else {
output.push(entry);
}
});
};
const fetchFiles = async (from, to) => {
try {
const urls = await getListLog(from, to);
if (!urls || urls.length === 0) {
console.log("No logs found");
return [];
}
const fileContents = await Promise.all(
urls.map((u) => fetchWithRetry(u?.split(".log")[0]+".log"))
);
let report: any = [];
fileContents.forEach((content, index) => {
const lines = content?.split("\n");
if (!lines) return;
const fName = path.basename(urls[index] ?? "").trim();
const output = [];
lines.forEach((line, i) => {
const lineResult = extractInfoFromLine(line, i, fName);
mergeLines(output, lineResult);
});
report = [...report, ...output];
});
const finalReport = report.filter(
(i) => i.SN && /^[A-Z0-9-]{5,}$/.test(i.SN) && i.PID
);
fs.writeFileSync(
"./app/utils/indexSN.txt",
JSON.stringify(finalReport, null, 2).replace(/\\u0000/g, ""),
"utf-8"
);
console.log("Write loggg !");
return finalReport;
} catch (error) {
console.error("GET INFORMATION FAIL", error);
throw error;
}
};
const result = await fetchFiles(from, to);
response.status(200).json(result);
}
/**
* Controller lay noi dung file log theo so dong
* @param {String} fileName url file log tren server log
* @param {Integer} line dong chua serial number trong log
* @param {Integer} range khoang dong truoc/sau line
* @author {Token} req.headers.authorization //token xac thuc
*/
public async getParagraph({ request, response }: HttpContextContract) {
const { fileName, line, range } = request.all();
try {
let fName =
fileName.search("AUTO") !== -1 ? "AUTOlog/" + fileName : fileName;
const res = await axios.get(BASE_URL + "/" + fName);
const arrayLine = res?.data?.split("\n");
if (Number(range) >= Number(line)) {
response.status(200).json({
content: arrayLine?.slice(0, line + range)?.join("\n"),
});
} else {
response.status(200).json({
content: arrayLine?.slice(line - range - 1, line + range)?.join("\n"),
});
}
} catch (error) {
console.log(error);
response.status(202).send({ mess: "FILE NOT FOUND", error: error });
}
}
public async store({ request, response }: HttpContextContract) {}
public async show({}: HttpContextContract) {}
public async edit({}: HttpContextContract) {}
public async update({}: HttpContextContract) {}
public async destroy({}: HttpContextContract) {}
}