-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate-playlists-stats.mjs
82 lines (66 loc) · 2.41 KB
/
generate-playlists-stats.mjs
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
79
80
81
82
import { readFile, writeFile, access } from "fs/promises";
import { resolve as resolvePath } from "path";
// Params
const csvFilePath = 'playlists_stats.csv';
const basePicturesPath = "./public"
const outputFilePath = 'playlists_stats.json';
// First line are headers
const numberOfHeaders = 1;
// Functions
const generateImagePath = (playlistId) => resolvePath(`${basePicturesPath}/covers/${playlistId}/cover.webp`);
// Function to parse CSV lines with quotes handling
function parseCSVLine(line) {
const result = [];
let inQuotes = false;
let field = '';
for (let char of line) {
if (char === '"') {
inQuotes = !inQuotes; // Toggle the quotes flag
field += char; // Add the quote character to the field
} else if (char === ',' && !inQuotes) {
result.push(field); // Push the field if not inside quotes
field = ''; // Reset field for the next column
} else {
field += char; // Add character to the current field
}
}
// Push the last field
result.push(field);
return result.map(f => f.replace(/^"|"$/g, '').replace(/""/g, '"')); // Remove surrounding quotes and double quotes
}
async function readCSV(filePath) {
const data = await readFile(filePath, 'utf8');
const rows = data.split('\n').slice(numberOfHeaders);
const games = [];
for(let game of rows) {
const columns = parseCSVLine(game);
// Check if it is a real line or not
if (columns.length < 4) continue;
const [playlistId, title, views, watchTimeInMinutes] = columns;
const imagePath = generateImagePath(playlistId);
// Check if it is a gaming playlist
// How ? Local image path must exist ;)
try {
await access(imagePath);
games.push({
id: playlistId,
title: title,
imagePath: imagePath,
views: Number.parseInt(views),
watchTimeInMinutes: Number(watchTimeInMinutes)
});
} catch {
console.log(`\t ${title} is not a game - skipping`);
continue;
}
}
return games;
}
async function writeJSON(filePath, data) {
await writeFile(filePath, JSON.stringify(data, null, 2));
}
async function generateData() {
const games = await readCSV(csvFilePath);
await writeJSON(outputFilePath, games);
}
generateData();