Files
web/apps/base-docs/scripts/updateTutorials.js
Cypher Pepe 9785ddfd85 Update updateTutorials.js (#612)
This code improves error handling, is made more readable, and uses asynchronous fs.promises operations for a more modern approach to reading files and working with the file system.
2024-07-09 12:34:35 -04:00

94 lines
2.8 KiB
JavaScript

const yaml = require('js-yaml');
const fs = require('fs');
const { readFile, readdir, stat } = fs.promises;
const path = require('path');
const crypto = require('crypto');
const tutorialsDir = path.join(__dirname, '..', 'tutorials', 'docs');
const outputFilePath = path.join(__dirname, '..', 'tutorials', 'data.json');
async function getDuration(filePath) {
try {
const content = await readFile(filePath, 'utf8');
const words = content.trim().split(/\s+/).length;
const averageReadingSpeed = 225;
const readingTimeMinutes = (words / averageReadingSpeed) * 2;
const hours = Math.floor(readingTimeMinutes / 60);
const minutes = Math.round(readingTimeMinutes % 60);
let timeString = '';
if (hours > 0) {
timeString += `${hours} hr `;
}
timeString += `${minutes} min`;
return `${timeString} read`;
} catch (error) {
console.error('Error reading file:', error);
return null;
}
}
async function formatDate(date) {
const months = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
];
const month = months[date.getMonth()];
const day = date.getDate();
const year = date.getFullYear();
return `${month} ${day}, ${year}`;
}
async function calculateChecksum(filePath) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha256');
const stream = fs.createReadStream(filePath);
stream.on('data', (data) => hash.update(data));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', reject);
});
}
(async () => {
const tutorials = {};
let existingData = {};
try {
existingData = JSON.parse(await readFile(outputFilePath, 'utf8'));
} catch (e) {
console.error('Failed to read existing data:', e);
}
try {
const files = await readdir(tutorialsDir);
for (const file of files) {
const tutorialsPath = path.join(tutorialsDir, file);
const tutorialsStat = await stat(tutorialsPath);
if (tutorialsStat.isFile()) {
let content = await readFile(tutorialsPath, 'utf8');
const frontMatter = yaml.load(content.split('---\n')[1]);
const slug = path.parse(file).name;
const checksum = await calculateChecksum(tutorialsPath);
const currentDate = new Date();
if (!existingData[slug] || existingData[slug].checksum !== checksum) {
tutorials[slug] = {
...frontMatter,
last_updated: await formatDate(currentDate),
duration: await getDuration(tutorialsPath),
checksum: checksum,
};
} else {
tutorials[slug] = existingData[slug];
}
}
}
} catch (e) {
console.error('Error updating tutorial data:', e);
}
fs.writeFileSync(outputFilePath, JSON.stringify(tutorials, null, 4));
})();