c3d2-web/scripts/ds2013-resources.js

190 lines
4.9 KiB
JavaScript
Raw Normal View History

2013-09-14 00:12:42 +02:00
var ltx = require('ltx');
var http = require('http');
var fs = require('fs');
var url = require('url');
var running = 0, queue = [];
var SUFFIXES = [".mp4", ".webm", ".mp3", "_hq.mp4"];
2013-10-08 01:06:02 +02:00
var WEB_SUFFIXES = [".mp4", ".webm", ".mp3"];
2013-09-14 00:12:42 +02:00
function resolveSizes(urls, cb) {
if (running > 0) {
queue.push(function() {
resolveSizes(urls, cb);
});
return;
}
running++;
urls = urls.map(url.parse);
var pending = 0, results = [],
done = function() {
if (pending < 1) {
results = results.sort(function(r1, r2) {
var ui1 = urls.indexOf(r1.url);
var ui2 = urls.indexOf(r2.url);
if (ui1 < ui2)
2013-09-14 00:12:42 +02:00
return -1;
else if (ui1 > ui2)
2013-09-14 00:12:42 +02:00
return 1;
else
return 0;
});
cb(results);
running--;
var f = queue.shift();
f && f();
}
};
urls.forEach(function(u) {
var req = http.request({ method: 'HEAD',
path: u.pathname,
hostname: u.host });
req.end();
req.on('response', function(res) {
if (res.statusCode === 200) {
results.push({ url: url.format(u),
size: res.headers['content-length'] });
} else {
console.error("HTTP " + res.statusCode + " " + u.pathname);
}
pending--;
done();
});
pending++;
});
done();
}
function mimeByExt(url) {
var ext = url.split('.').pop();
var type = ({ avi: 'video/avi',
2013-10-08 01:06:02 +02:00
mp3: 'audio/mpeg',
2013-09-14 00:12:42 +02:00
mp4: 'video/mp4',
webm: 'video/webm',
ogv: 'video/ogg',
flv: 'video/x-flv' })[ext];
return type || 'application/octet-stream';
}
function processEvent(event) {
var base = 'http://ftp.c3d2.de/datenspuren/2013/' + event.outputName;
var urls = WEB_SUFFIXES.map(function(fmt) {
return base + fmt;
});
resolveSizes(urls, function(infos) {
infos = infos.filter(function(i) {
return i.size !== undefined;
});
if (infos.length < 1) {
console.warn("<!-- No resources for " + event.id + ": " + event.title + " -->");
return;
}
var resAttrs = {
title: event.title,
size: infos[0].size,
type: mimeByExt(infos[0].url),
url: infos[0].url,
preview: base + ".gif",
poster: base + ".jpg"
};
if (event.id != "0000") {
resAttrs['details-link'] = "http://datenspuren.de/2013/fahrplan/events/" +
event.id + ".html";
resAttrs['feedback-link'] = "https://frab.cccv.de/en/DS2013/public/events/" +
event.id + "/feedback/new";
}
var res = new ltx.Element('resource', resAttrs);
infos.slice(1).forEach(function(info) {
res.c('alternative', { size: info.size,
type: mimeByExt(info.url),
url: info.url });
});
console.info(res.toString());
});
}
function printMetadata(event) {
var metaparameters = "";
function addMeta(k, v) {
metaparameters +=
" -metadata " + k + "=\"" +
v.replace(/"/g, '\\"') + "\"";
}
addMeta('title', event.title);
addMeta('subtitle', event.subtitle);
addMeta('album', "Datenspuren 2012");
addMeta('artist', "Datenspuren");
addMeta('author', "Datenspuren");
addMeta('language', "deu");
addMeta('year', "2012");
addMeta('composer', event.persons.join(", "));
addMeta('description', event.abstract || event.description);
SUFFIXES.forEach(function(suffix) {
console.log("avconv -i " + event.inputName + suffix + " -codec copy" + metaparameters + " -y " + event.outputName + suffix);
});
}
function slugify(title) {
return title.toLowerCase().
replace(/\s*[\-\:].*/, "").
replace(/[\.!\?\/]/g, "").
replace(/Ä/g, "Ae").
replace(/Ö/g, "Oe").
replace(/Ü/g, "Ue").
replace(/ä/g, "ae").
replace(/ö/g, "oe").
replace(/ü/g, "ue").
replace(/ß/g, "ss").
replace(/ẞ/g, "SS").
replace(/\s+/g, "_");
}
function makeEvent(event) {
event.inputName = event.id;
event.outputName = event.id + "_" + slugify(event.title);
return event;
}
var scheduleFile = fs.readFileSync('../content/static/datenspuren/2013/fahrplan/schedule.xml');
var schedule = ltx.parse(scheduleFile);
schedule.getChildren('day').forEach(function(dayEl) {
var dayEvents = [];
var roomIdx = 0;
dayEl.getChildren('room').forEach(function(roomEl) {
roomEl.getChildren('event').forEach(function(eventEl) {
var persons = [];
eventEl.getChildren('persons').forEach(function(personsEl) {
personsEl.getChildren('person').forEach(function(personEl) {
persons.push(personEl.getText());
});
});
dayEvents.push(makeEvent(
{ id: eventEl.attrs.id,
time: eventEl.getChildText('start'),
room: roomIdx,
title: eventEl.getChildText('title'),
subtitle: eventEl.getChildText('subtitle'),
slug: eventEl.getChildText('slug'),
abstract: eventEl.getChildText('abstract'),
description: eventEl.getChildText('description'),
persons: persons
}));
});
roomIdx++;
});
dayEvents = dayEvents.sort(function(e1, e2) {
return (e1.time < e2.time) ? -1 :
((e1.time > e2.time) ? 1 : e1.room - e2.room);
});
dayEvents.forEach(printMetadata);
dayEvents.forEach(processEvent);
});