import express from 'express'; import { exploreVideos, toGraphviz } from '../lib/explore.mjs'; import { toSVG } from '../lib/graphviz.mjs'; const router = express.Router(); export default router; const statusPending = Symbol('PENDING'); const statusError = Symbol('ERROR'); const cache = Object.create(null); // Extract the video ID from a YouTube URL const YOUTUBE_URL_REGEX = /(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?v=([^?&]+)/; const YOUTUBE_SHORT_URL_REGEX = /(?:https?:\/\/)?(?:www\.)?youtu\.be\/([^?&]+)/; router.post('/', (req, res) => { if (req.body.url === '') { res.redirect('/'); return; } const url = req.body.url.match(YOUTUBE_URL_REGEX); if (url !== null) { res.redirect(`/mazes/${url[1]}`); return; } const shortURL = req.body.url.match(YOUTUBE_SHORT_URL_REGEX); if (shortURL !== null) { res.redirect(`/mazes/${shortURL[1]}`); return; } res.redirect(`/mazes/${req.body.url}`); }); // Generate the graph for a given video ID router.get('/:videoId', async (req, res) => { const {videoId} = req.params; if (videoId in cache) { if (cache[videoId] === statusPending) { res.header('Refresh', '5'); res.send('Exploration in progress… Please wait.'); } else if (cache[videoId] === statusError) { res.status(500).send('Error'); } else { res.send(cache[videoId]); } } else { cache[videoId] = statusPending; res.header('Refresh', '1'); res.send('Exploration in progress… Please wait.'); try { const graph = await exploreVideos(req.params.videoId); const graphviz = toGraphviz(...graph); const svg = await toSVG(graphviz); cache[videoId] = svg; } catch (err) { console.error(err); cache[videoId] = statusError; } } });