'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); // const remaining = ids.filter(id => videos[id] === undefined); // 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);