Compare commits

..

No commits in common. "bf2730f991dd8a56d0d4416a48fcb18c498efc50" and "aec7db0183ada9cec57d55b53acede8efe1c51d4" have entirely different histories.

2 changed files with 23 additions and 38 deletions

View File

@ -10,10 +10,9 @@ const GRAPH_LINK = ' "%s" -> "%s"';
* *
* @async * @async
* @param string videoId Source video identifier. * @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. * @return Array.<Object, Object> Nodes and set of neighbors of each node.
*/ */
export const exploreVideos = async (videoId, onUpdate) => export const exploreVideos = async videoId =>
{ {
// Store metadata about each visited video // Store metadata about each visited video
const videosNodes = Object.create(null); const videosNodes = Object.create(null);
@ -28,28 +27,25 @@ export const exploreVideos = async (videoId, onUpdate) =>
while (queue.length > 0) while (queue.length > 0)
{ {
const currentId = queue.shift(); const currentId = queue.shift();
const config = await api.getPlayerConfig(currentId);
const meta = api.getVideoMeta(config);
if (!(currentId in videosNodes)) 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])
{ {
const config = await api.getPlayerConfig(currentId); if (!(nextId in videosNodes))
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); queue.push(nextId);
} }
} }
onUpdate(Object.keys(videosNodes).length, queue.length);
} }
return [videosNodes, nextVideos]; return [videosNodes, nextVideos];

View File

@ -5,7 +5,6 @@ import { toSVG } from '../lib/graphviz.mjs';
const router = express.Router(); const router = express.Router();
export default router; export default router;
const statusDone = Symbol('DONE');
const statusPending = Symbol('PENDING'); const statusPending = Symbol('PENDING');
const statusError = Symbol('ERROR'); const statusError = Symbol('ERROR');
const cache = Object.create(null); const cache = Object.create(null);
@ -46,47 +45,37 @@ router.get('/:videoId', async (req, res) => {
if (videoId in cache) if (videoId in cache)
{ {
if (cache[videoId][0] === statusPending) if (cache[videoId] === statusPending)
{ {
res.header('Refresh', '5'); res.header('Refresh', '5');
res.send(`Exploration in progress, please wait.<br> res.send('Exploration in progress… Please wait.');
${cache[videoId][1]}`);
} }
else if (cache[videoId][0] === statusError) else if (cache[videoId] === statusError)
{ {
res.status(500).send('Error'); res.status(500).send('Error');
} }
else else
{ {
res.send(cache[videoId][1]); res.send(cache[videoId]);
} }
} }
else else
{ {
cache[videoId] = [statusPending, 'Starting exploration']; cache[videoId] = statusPending;
res.header('Refresh', '1'); res.header('Refresh', '1');
res.send('Exploration in progress, please wait.'); res.send('Exploration in progress… Please wait.');
try try
{ {
const graph = await exploreVideos(req.params.videoId, (done, rem) => const graph = await exploreVideos(req.params.videoId);
{
cache[videoId] = [
statusPending,
`${done} videos explored, ${rem} pending`
];
});
cache[videoId] = [statusPending, 'Converting graph to SVG'];
const graphviz = toGraphviz(...graph); const graphviz = toGraphviz(...graph);
const svg = await toSVG(graphviz); const svg = await toSVG(graphviz);
cache[videoId] = svg;
cache[videoId] = [statusDone, svg];
} }
catch (err) catch (err)
{ {
console.error(err); console.error(err);
cache[videoId] = [statusError]; cache[videoId] = statusError;
} }
} }
}); });