Compare commits
	
		
			2 Commits
		
	
	
		
			aec7db0183
			...
			bf2730f991
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | bf2730f991 | |
|  | bd2300303b | 
|  | @ -10,9 +10,10 @@ const GRAPH_LINK = '    "%s" -> "%s"'; | |||
|  * | ||||
|  * @async | ||||
|  * @param string videoId Source video identifier. | ||||
|  * @param function onUpdate Callback run every time a new video is explored. | ||||
|  * @return Array.<Object, Object> Nodes and set of neighbors of each node. | ||||
|  */ | ||||
| export const exploreVideos = async videoId => | ||||
| export const exploreVideos = async (videoId, onUpdate) => | ||||
| { | ||||
|     // Store metadata about each visited video
 | ||||
|     const videosNodes = Object.create(null); | ||||
|  | @ -27,25 +28,28 @@ export const exploreVideos = async videoId => | |||
|     while (queue.length > 0) | ||||
|     { | ||||
|         const currentId = queue.shift(); | ||||
|         const config = await api.getPlayerConfig(currentId); | ||||
|         const meta = api.getVideoMeta(config); | ||||
| 
 | ||||
|         videosNodes[currentId] = meta; | ||||
|         nextVideos[currentId] = new Set(); | ||||
| 
 | ||||
|         // Add links between this video and the linked ones
 | ||||
|         api.getEndScreenVideos(config) | ||||
|             .forEach(nextId => nextVideos[meta.videoId].add(nextId)); | ||||
|         api.getCardVideos(config) | ||||
|             .forEach(nextId => nextVideos[meta.videoId].add(nextId)); | ||||
| 
 | ||||
|         for (let nextId of nextVideos[meta.videoId]) | ||||
|         if (!(currentId in videosNodes)) | ||||
|         { | ||||
|             if (!(nextId in videosNodes)) | ||||
|             const config = await api.getPlayerConfig(currentId); | ||||
|             const meta = api.getVideoMeta(config); | ||||
| 
 | ||||
|             videosNodes[currentId] = meta; | ||||
|             nextVideos[currentId] = new Set(); | ||||
| 
 | ||||
|             // Add links between this video and the linked ones
 | ||||
|             api.getEndScreenVideos(config) | ||||
|                 .forEach(nextId => nextVideos[meta.videoId].add(nextId)); | ||||
|             api.getCardVideos(config) | ||||
|                 .forEach(nextId => nextVideos[meta.videoId].add(nextId)); | ||||
| 
 | ||||
|             for (let nextId of nextVideos[meta.videoId]) | ||||
|             { | ||||
|                 queue.push(nextId); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         onUpdate(Object.keys(videosNodes).length, queue.length); | ||||
|     } | ||||
| 
 | ||||
|     return [videosNodes, nextVideos]; | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import { toSVG } from '../lib/graphviz.mjs'; | |||
| const router = express.Router(); | ||||
| export default router; | ||||
| 
 | ||||
| const statusDone = Symbol('DONE'); | ||||
| const statusPending = Symbol('PENDING'); | ||||
| const statusError = Symbol('ERROR'); | ||||
| const cache = Object.create(null); | ||||
|  | @ -45,37 +46,47 @@ router.get('/:videoId', async (req, res) => { | |||
| 
 | ||||
|     if (videoId in cache) | ||||
|     { | ||||
|         if (cache[videoId] === statusPending) | ||||
|         if (cache[videoId][0] === statusPending) | ||||
|         { | ||||
|             res.header('Refresh', '5'); | ||||
|             res.send('Exploration in progress… Please wait.'); | ||||
|             res.send(`Exploration in progress, please wait.<br>
 | ||||
| ${cache[videoId][1]}…`);
 | ||||
|         } | ||||
|         else if (cache[videoId] === statusError) | ||||
|         else if (cache[videoId][0] === statusError) | ||||
|         { | ||||
|             res.status(500).send('Error'); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             res.send(cache[videoId]); | ||||
|             res.send(cache[videoId][1]); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         cache[videoId] = statusPending; | ||||
|         cache[videoId] = [statusPending, 'Starting exploration']; | ||||
|         res.header('Refresh', '1'); | ||||
|         res.send('Exploration in progress… Please wait.'); | ||||
|         res.send('Exploration in progress, please wait.'); | ||||
| 
 | ||||
|         try | ||||
|         { | ||||
|             const graph = await exploreVideos(req.params.videoId); | ||||
|             const graph = await exploreVideos(req.params.videoId, (done, rem) => | ||||
|             { | ||||
|                 cache[videoId] = [ | ||||
|                     statusPending, | ||||
|                     `${done} videos explored, ${rem} pending` | ||||
|                 ]; | ||||
|             }); | ||||
| 
 | ||||
|             cache[videoId] = [statusPending, 'Converting graph to SVG']; | ||||
|             const graphviz = toGraphviz(...graph); | ||||
|             const svg = await toSVG(graphviz); | ||||
|             cache[videoId] = svg; | ||||
| 
 | ||||
|             cache[videoId] = [statusDone, svg]; | ||||
|         } | ||||
|         catch (err) | ||||
|         { | ||||
|             console.error(err); | ||||
|             cache[videoId] = statusError; | ||||
|             cache[videoId] = [statusError]; | ||||
|         } | ||||
|     } | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue