82 lines
2.2 KiB
JavaScript
82 lines
2.2 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';
|
|||
|
|
|||
|
// 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(() =>
|
|||
|
{
|
|||
|
const dest = path.join(__dirname, '../maze.dot');
|
|||
|
console.log('Terminé. Résultat dans ' + dest);
|
|||
|
|
|||
|
fs.writeFileSync(
|
|||
|
dest,
|
|||
|
graphToDOT(
|
|||
|
videosGraph,
|
|||
|
id => videosMeta[id].title,
|
|||
|
id => util.format(YOUTUBE_WATCH, id)
|
|||
|
)
|
|||
|
);
|
|||
|
}).catch(console.error);
|