90 lines
2.3 KiB
JavaScript
90 lines
2.3 KiB
JavaScript
'use strict';
|
||
|
||
const Graph = require('graph-data-structure');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const util = require('util');
|
||
|
||
const {getEndScreenVideos, getCardVideos} = require('./api');
|
||
const {graphToDOT} = require('./graph');
|
||
|
||
const YOUTUBE_WATCH = 'https://youtu.be/%s';
|
||
|
||
// Récupère le chemin vers le fichier de sortie depuis la ligne de commande
|
||
if (process.argv.length !== 3)
|
||
{
|
||
console.error(`Utilisation : node src [sortie]`);
|
||
process.exit(1);
|
||
}
|
||
|
||
const dest = process.argv[2];
|
||
|
||
// Graphe des vidéos. Chaque nœud est une vidéo, et est liée à toutes
|
||
// les vidéos vers lesquelles elle a un lien (par carte ou écran de fin)
|
||
const videosGraph = Graph();
|
||
|
||
// Stocke les métadonnées de chaque vidéo
|
||
const videosMeta = Object.create(null);
|
||
|
||
// Se souvient des vidéos déja visitées
|
||
const visitedVideos = Object.create(null);
|
||
|
||
/**
|
||
* Explore récursivement les liens d’une vidéo pour remplir le graphe
|
||
* des vidéos.
|
||
*
|
||
* @param videoId Identifiant de la vidéo source.
|
||
*/
|
||
const exploreVideo = videoId =>
|
||
{
|
||
// S’assure de ne pas visiter deux fois la même vidéo
|
||
if (visitedVideos[videoId] === true)
|
||
{
|
||
return Promise.resolve();
|
||
}
|
||
|
||
visitedVideos[videoId] = true;
|
||
|
||
return Promise.all([
|
||
getEndScreenVideos(videoId),
|
||
getCardVideos(videoId)
|
||
]).then(results =>
|
||
{
|
||
const videos = [].concat(...results);
|
||
const ids = videos.map(video => video.videoId);
|
||
|
||
// Ajout des vidéos liées dans les métadonnées
|
||
videos.forEach(video => videosMeta[video.videoId] = video);
|
||
|
||
// Ajout des liens entre la vidéo et ses vidéos liées
|
||
ids.forEach(id => videosGraph.addEdge(videoId, id));
|
||
|
||
// Récursion sur les vidéos non-explorées
|
||
return Promise.all(ids.map(id => exploreVideo(id)));
|
||
});
|
||
};
|
||
|
||
// Métadonnées de la vidéo source
|
||
const rootVideoId = 'EZGra6O8ClQ';
|
||
videosMeta[rootVideoId] = {
|
||
title: '1 avril 2017 : présentation des règles',
|
||
videoId: rootVideoId,
|
||
links: []
|
||
};
|
||
|
||
console.log('Démarrage de l’exploration !');
|
||
|
||
exploreVideo(rootVideoId).then(() =>
|
||
{
|
||
fs.writeFileSync(
|
||
dest,
|
||
graphToDOT(
|
||
videosGraph,
|
||
id => videosMeta[id].title,
|
||
id => util.format(YOUTUBE_WATCH, id)
|
||
)
|
||
);
|
||
|
||
console.log('Terminé. Résultat dans ' + dest);
|
||
}).catch(console.error);
|