implemented detailed endpoint
This commit is contained in:
130
src/use-cases/parse-detailed-category-use-case.js
Normal file
130
src/use-cases/parse-detailed-category-use-case.js
Normal file
@@ -0,0 +1,130 @@
|
||||
const { exec } = require("node:child_process")
|
||||
|
||||
class ParseDetailedCategoryUseCase {
|
||||
constructor({ categoryConverter }) {
|
||||
this.categoryConverter = categoryConverter;
|
||||
}
|
||||
|
||||
execute(domain) {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`echo ${domain} | bin/gcf1check.sh etc check_categorize_hybrid`,
|
||||
{ cwd: '/usr/local/gcf1' },
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = this.parseOutput(stdout);
|
||||
resolve(parsed);
|
||||
} catch (parseError) {
|
||||
console.error('Parse error:', parseError);
|
||||
reject(parseError);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
parseOutput(output) {
|
||||
// Extract all quoted strings in order
|
||||
const quotedStrings = [];
|
||||
const quoteRegex = /"([^"]*)"/g;
|
||||
let match;
|
||||
while ((match = quoteRegex.exec(output)) !== null) {
|
||||
quotedStrings.push(match[1]);
|
||||
}
|
||||
|
||||
// Split on whitespace
|
||||
const parts = output.trim().split(/\t|\s{2,}/);
|
||||
|
||||
// Find numeric IDs by looking for numbers that appear in sequence
|
||||
// After "Categorized", we have: count, primary_id, secondary_id, ..., reputation_score, ..., age_rating_score
|
||||
|
||||
// Primary ID is parts[2] (always third element after "Categorized" and count)
|
||||
const primary = parts[2];
|
||||
const primaryName = quotedStrings[0];
|
||||
|
||||
// Secondary ID is parts[4] (always fifth element)
|
||||
const secondary = parts[4];
|
||||
|
||||
let secondaryName = '';
|
||||
let quotedIndex = 1; // Start after primary name
|
||||
|
||||
// If secondary is not "0", it has a quoted name
|
||||
if (secondary !== '0' && secondary !== '-') {
|
||||
secondaryName = quotedStrings[quotedIndex];
|
||||
quotedIndex++;
|
||||
} else {
|
||||
secondaryName = parts[5] === '-' ? '-' : parts[5];
|
||||
}
|
||||
|
||||
// Find reputation score - it's a single digit that comes after some markers
|
||||
// Look for the pattern: a digit followed by a quoted reputation name
|
||||
let reputation = '';
|
||||
let reputationName = '';
|
||||
|
||||
// Scan from parts[7] onwards to find reputation (it's usually around parts[8-11])
|
||||
for (let i = 7; i < parts.length; i++) {
|
||||
const part = parts[i];
|
||||
// Look for single/double digit that's not a category ID
|
||||
if (!isNaN(part) && part !== '-' && !part.includes('x') && !part.includes('|')) {
|
||||
const num = parseInt(part);
|
||||
// Reputation scores are typically 0-5, single digit
|
||||
if (num >= 0 && num <= 5 && parts[i+1] !== '-' && !parts[i+1].includes('0x')) {
|
||||
reputation = part;
|
||||
reputationName = quotedStrings[quotedIndex];
|
||||
quotedIndex++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find age rating - it's another single digit that comes after more markers
|
||||
// After reputation, we should find age rating
|
||||
let ageRating = '';
|
||||
let ageRatingName = '';
|
||||
|
||||
for (let i = 12; i < parts.length; i++) {
|
||||
const part = parts[i];
|
||||
if (!isNaN(part) && part !== '-' && !part.includes('x') && !part.includes('|')) {
|
||||
const num = parseInt(part);
|
||||
if (num >= 0 && num <= 5) {
|
||||
// Make sure it's not already used as reputation
|
||||
if (part !== reputation || i > 10) {
|
||||
ageRating = part;
|
||||
ageRatingName = quotedStrings[quotedIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert category IDs using the mapper
|
||||
const primaryMapped = this.categoryConverter.execute(primary);
|
||||
const secondaryMapped = secondary !== '-' && secondary !== '0' ?
|
||||
this.categoryConverter.execute(secondary) : null;
|
||||
|
||||
// Build result array in the same format as the / endpoint (as strings)
|
||||
const resultArray = [String(primaryMapped)];
|
||||
if (secondaryMapped !== null) {
|
||||
resultArray.push(String(secondaryMapped));
|
||||
}
|
||||
|
||||
return {
|
||||
result: resultArray,
|
||||
primary: primaryMapped,
|
||||
primary_name: primaryName,
|
||||
secondary: secondaryMapped,
|
||||
secondary_name: secondaryName,
|
||||
reputation: parseInt(reputation),
|
||||
reputation_name: reputationName,
|
||||
age_rating: parseInt(ageRating),
|
||||
age_rating_name: ageRatingName,
|
||||
raw_output: output.trim()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { ParseDetailedCategoryUseCase }
|
||||
Reference in New Issue
Block a user