var walk = require('walk'); var fs = require('fs'); var path = require('path'); var ical = require('ical'); var forEachAsync = require('forEachAsync'); var walker; var watcher; var configuration; var files = []; exports.start = function(config) { configuration = config; if(typeof configuration.ignoreDotFiles !== 'undefined' && configuration.ignoreDotFiles == 'false') { watcher = require('watch-tree').watchTree(configuration.rootDir, {}); } else { watcher = require('watch-tree').watchTree(configuration.rootDir, {ignore: '.*'}); } watcher.on('fileDeleted', exports.rebuildFiles); watcher.on('fileCreated', exports.rebuildFiles); watcher.on('fileModified', exports.rebuildFiles); exports.rebuildFiles(); }; exports.rebuildFiles = function() { console.log('rebuilding...'); walker = walk.walk(configuration.rootDir, { followLinks: false }); var newSlides = {}; walker.on("directories", function (root, dirAr, next) { var lastDir = path.join(__dirname, root).split('/'); if((lastDir.length - __dirname.split('/').length) < 2) { dirAr.forEach(function(dir) { newSlides[dir.name] = { name: dir.name, template: '', slides: []}; }); } next(); }).on("file", function(root, fileStats, next) { if(fileStats.name == configuration.descriptionFile || fileStats.name == configuration.eventFile) { next(); } else if(fileStats.name == configuration.templateFile) { var lastDir = root.split('/'); newSlides[lastDir[lastDir.length - 1]]['template'] = path.join(lastDir[lastDir.length - 1], fileStats.name); next(); } else { var lastDir = path.join(root).split('/'); if(newSlides.hasOwnProperty(lastDir[lastDir.length - 1])) { var ext = path.extname(fileStats); var type = 'image'; switch (ext) { case '.mp4': case '.avi': case '.ogv': case '.mkv': type = 'video'; break; } newSlides[lastDir[lastDir.length - 1]]['slides'].push({ type: type, file: path.join(lastDir[lastDir.length - 1], fileStats.name), head: '', text: ''}); } next(); } }).on("errors", function(root, nodeStatsArray, next) { next(); }).on("end", function() { for(var slideset in newSlides) { /* collects descriptions and adds them to the slideset */ var collectDescs = function(slideset) { fs.readFile(path.join(__dirname, configuration.rootDir, slideset, configuration.descriptionFile), function(err, data) { if(err) { setSlides(slideset, newSlides[slideset], function(err) { if(err) { throw err}}); return; } var descs = JSON.parse(data.toString()); for(var file in newSlides[slideset]['slides']) { if(!newSlides[slideset]['slides'].hasOwnProperty(file)) { continue; } if(!newSlides[slideset]['slides'][file].hasOwnProperty('file')) { continue; } for(var desc in descs) { if(!descs.hasOwnProperty(desc)) { continue; } var comp = newSlides[slideset]['slides'][file]['file'].split('/'); if(descs[desc]['file'] == comp[comp.length - 1]) { newSlides[slideset]['slides'][file]['head'] = descs[desc]['head']; newSlides[slideset]['slides'][file]['text'] = descs[desc]['text']; } } } setSlides(slideset, newSlides[slideset], function(err) { if(err) { throw err; }}); }); } /* collect events and adds them to the slideset */ var collectEvents = function(slideset) { fs.readFile(path.join(__dirname, configuration.rootDir, slideset, configuration.eventFile), function(err, data) { if(err) { return; } try { var events = JSON.parse(data.toString()); } catch(e) { return; } if(events['type'] == 'text') { setEvents(slideset, events['events'], function(err) { if(err) { throw err; } }); } else if(events['type'] == 'ical') { ical.fromURL(events['url'], {}, function(err, bloat) { if(err) { throw err; } var bDate = new Date(); var fDate = new Date(); bDate.setMinutes(bDate.getMinutes() - events['before']); fDate.setMinutes(bDate.getMinutes() + events['after']); var data = ical.events_between(bDate, fDate); var compEv = []; for (var k in data) { if (!data.hasOwnProperty(k)) { continue; } var ev = data[k]; if(ev.start && ev.summary) { var dateStr = ev.start.toLocaleDateString(); ev.start = ev.start.toLocaleTimeString(); ev.end = ev.end.toLocaleTimeString(); delete ev.rrule; delete ev.uid; delete ev.type; for(var i in ev) { if(!ev.hasOwnProperty(i)) { continue; } if(typeof ev[i] != 'string') { continue; } ev[i] = ev[i].replace(/\\,/g, ','); } if(typeof compEv[dateStr] == "undefined") { compEv[dateStr] = []; } compEv[dateStr].push(ev); } } setEvents(slideset, compEv, function(err) { if(err) { throw err; } }); }); } }); } collectDescs(slideset); collectEvents(slideset); } }); }; var setEvents = function(slideset, events, cb) { for (var searchset in files) { if(!files.hasOwnProperty(searchset)) { continue; } if(files[searchset].name == slideset) { files[searchset]['events'] = events; cb(null); return; } } cb('Couldn\'t find slideset'); }; var setSlides = function(slideName, newSlides, cb) { files[slideName] = newSlides; cb(null); }; exports.getSlides = function(slideset, cb) { for (var searchset in files) { if(!files.hasOwnProperty(searchset)) { continue; } if(files[searchset].name == slideset) { cb(null, files[searchset]); return; } } cb('Couldn\'t find slideset'); }; exports.getAllSlides = function(cb) { var slidesets = []; for(var slideset in files) { if(!files.hasOwnProperty(slideset)) { continue; } slidesets.push(files[slideset].name); } cb(slidesets); };