Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 5x 5x 5x 40x 40x 40x 28141x 35x 28106x 27845x 40x 5x 5x 5x 5x 70x 5x 27845x 27845x 27835x 27835x 27835x 5x 135045x 5x 70x 70x 5x 5x | /**
* @module generate-news-indexes/helpers/path-utils
* @description Filesystem helpers for the news directory ā root resolution
* and recursive article-HTML collection.
*
* @author Hack23 AB
* @license Apache-2.0
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import type { NewsArticleMetadata } from '../types.js';
import { LANGUAGES } from '../constants.js';
import { parseArticleMetadata } from './frontmatter.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/** Root news directory */
export const NEWS_DIR: string = path.join(__dirname, '..', '..', '..', 'news');
/**
* Collect all article HTML file paths recursively from a directory.
* Supports date-based subdirectory structure: news/{year}/{month}/article.html
*/
function collectArticleFiles(dir: string): string[] {
const result: string[] = [];
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
result.push(...collectArticleFiles(path.join(dir, entry.name)));
} else if (entry.isFile() && entry.name.endsWith('.html') && !entry.name.startsWith('index')) {
result.push(path.join(dir, entry.name));
}
}
return result;
}
/**
* Scan news directory and group articles by language.
* Supports date-based subdirectory structure: news/{year}/{month}/article.html
*/
export function scanNewsArticles(): Record<string, NewsArticleMetadata[]> {
console.log('\nš° Scanning for articles...');
const filePaths: string[] = collectArticleFiles(NEWS_DIR);
console.log(` Found ${filePaths.length} article files`);
const articlesByLang: Record<string, NewsArticleMetadata[]> = Object.fromEntries(
Object.keys(LANGUAGES).map((lang) => [lang, []]),
);
filePaths.forEach((filePath) => {
const metadata: NewsArticleMetadata | null = parseArticleMetadata(filePath);
if (metadata) {
metadata.slug = path.relative(NEWS_DIR, filePath).split(path.sep).join('/');
Eif (articlesByLang[metadata.lang]) {
articlesByLang[metadata.lang]!.push(metadata);
}
}
});
Object.keys(articlesByLang).forEach((lang) => {
articlesByLang[lang]?.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
});
const langCounts: string[] = Object.entries(articlesByLang)
.filter(([, arr]) => arr.length > 0)
.map(([lang, arr]) => `${lang.toUpperCase()} ${arr.length}`);
console.log(` š Articles by language: ${langCounts.length > 0 ? langCounts.join(', ') : 'none found'}`);
return articlesByLang;
}
|