Skip to content

Instantly share code, notes, and snippets.

@winguse
Created July 26, 2020 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save winguse/211d525d29d8a00353d5fcd6480f5dd0 to your computer and use it in GitHub Desktop.
Save winguse/211d525d29d8a00353d5fcd6480f5dd0 to your computer and use it in GitHub Desktop.
const http = require('http');
const { spawn } = require('child_process');
const jobs = {};
setInterval(() => {
Object.keys(jobs).forEach(url => {
const {ts} = jobs[url];
if (Date.now() - ts > 24 * 3600 * 1000) {
delete jobs[url];
}
})
}, 60 * 1000);
function download(url) {
if (jobs[url]) return;
const info = {
stdOut: '',
stdErr: '',
code: undefined,
ts: Date.now(),
};
jobs[url] = info;
const job = spawn('youtube-dl', [url]);
job.stdout.on('data', (data) => {
info.stdOut += data;
console.log(`${url} stdout: ${data}`);
});
job.stderr.on('data', (data) => {
info.stdErr += data;
console.error(`${url} stderr: ${data}`);
});
job.on('close', (code) => {
info.code = code;
console.log(`${url} exit with code ${code}`);
});
}
const server = http.createServer((req, res) => {
if (req.method === 'GET' && req.url && req.url.endsWith('/info.json')) {
res.writeHead(200, {
'content-type': 'application/json; utf-8',
});
res.end(JSON.stringify(jobs));
} else if (req.method === 'GET') {
res.writeHead(200, {
'content-type': 'text/html; utf-8',
});
res.end(`
<style>
html,body{
margin: 0;
padding: 0;
height: 100%;
}
.note {
text-align: center;
line-height: 3em;
font-size: 1em;
}
.verticalAccordion {
width: 100%;
}
.verticalAccordion ul {
width: 100%;
margin: 0;
padding: 0;
}
.verticalAccordion li {
list-style: none outside none;
display: block;
margin: 0;
padding: 0;
height: 40px;
width: 100%;
overflow: hidden;
background: #f0f0f0;
transition: height 0.3s ease-in-out;
}
.verticalAccordion h3 {
margin: 0;
padding: 10px;
height: 19px;
border-top: 1px solid #f0f0f0;
text-transform: uppercase;
color: #000;
background: #ccc;
cusor: pointer;
position: relative;
}
.verticalAccordion h3:before {
content:"";
border: 5px solid #000;
border-color: #000 transparent transparent;
position: absolute;
right: 10px;
top: 15px;
width: 0;
height: 0;
}
.verticalAccordion div {
margin: 0;
overflow: auto;
padding: 10px;
height: 220px;
}
.verticalAccordion li:hover {
height: 280px;
}
.verticalAccordion li:hover h3 {
color: #fff;
background: #000;
}
.verticalAccordion li:hover h3:before {
border-color: transparent transparent transparent #fff;
}
</style>
<body>
<h1 class="note">Drop the URL here.</h1>
<div class="verticalAccordion">
<ul id="ul">
</ul>
</div>
</body>
<script>
async function fetchInfo() {
const res = await fetch('./info.json');
const jobs = await res.json();
Object.keys(jobs).forEach(url => {
const ul = document.querySelector('#ul');
let li = document.querySelector(\`li[data-url='\${url}']\`);
if (!li) {
li = document.createElement('li');
li.dataset.url = url;
const h3 = document.createElement('h3');
h3.innerText = url;
li.append(h3);
const div = document.createElement('div');
li.append(div);
const stdout = document.createElement('h4')
stdout.innerText = 'StdOut';
const stderr = document.createElement('h4')
stderr.innerText = 'StdErr';
div.append(document.createElement('p'));
div.append(stdout);
div.append(document.createElement('pre'));
div.append(stderr);
div.append(document.createElement('pre'));
ul.append(li);
}
const {code, stdOut, stdErr, ts} = jobs[url];
li.querySelector('p').innerText = \`\${new Date(ts)}, \${ code === undefined ? 'processing...' : 'exit code: ' + code}\`;
const [stdoutEle, stderrEle] = li.querySelectorAll('pre');
stdoutEle.innerText = stdOut;
stderrEle.innerText = stdErr;
});
setTimeout(fetchInfo, 20 * 1000)
}
fetchInfo();
window.addEventListener("drop", async e => {
e.preventDefault();
e.stopPropagation();
await fetch('.', { method: 'POST', body: e.dataTransfer.getData('URL') })
fetchInfo();
});
window.addEventListener("dragover", e => e.preventDefault());
</script>`
);
} else {
let body = '';
req.on('data', data => {
body += data;
});
req.on('end', () => {
try {
new URL(body);
download(body);
res.writeHead(204);
res.end();
} catch (e) {
res.writeHead(403);
res.end('error url')
}
});
}
});
server.listen(4040, "127.0.0.1");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment