-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Big refactor with better dependency model
Modules don't know about each others and are orchestrated by app.js main application file
- Loading branch information
Showing
5 changed files
with
144 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,32 @@ | ||
var http = require('http'), | ||
fs = require('fs'), | ||
watch = require('node-watch'), | ||
path = require('path'), | ||
util = require('util'), | ||
log = require('npmlog'), | ||
url = require('url'), | ||
cfg = require('./config.json'), | ||
streamDirectoryContent = require('./stream.js'), | ||
generateFeed = require('./feed.js'); | ||
var log = require('npmlog'), | ||
cfg = require('./lib/config.json'), | ||
server = require('./lib/server.js'), | ||
watcher = require('./lib/watcher.js'), | ||
feed = require('./lib/feed.js'); | ||
|
||
/** | ||
* TODO: | ||
* Use more async calls with promises. | ||
* Prevent watcher to get crazy when copying a big file over | ||
*/ | ||
|
||
//Fix music folder setting so we accept string, but work with array | ||
if (! util.isArray(cfg.music_folder)) { | ||
cfg.music_folder = [ cfg.music_folder ]; | ||
} | ||
var xml = "generating xml..."; | ||
|
||
/* Server part */ | ||
http.createServer(function (req, res) { | ||
res.on('sendStarted', function() { | ||
log.info( | ||
'server', '[%s] %s %s (%d)', | ||
req.connection.remoteAddress, req.method, req.url, res.statusCode | ||
); | ||
var folders = cfg.music_folder || "."; | ||
var port = cfg.port || 3333; | ||
var feedinfo = cfg.feed || { | ||
"title": "Feed Title", | ||
"description": "A great feed", | ||
"feed_url": "127.0.0.1", | ||
"site_url": "127.0.0.1" | ||
}; | ||
var url = feedinfo.feed_url || "127.0.0.1"; | ||
|
||
var webserver = server.startServer(xml, folders, port, url); | ||
watcher.startWatching(folders, function() { | ||
feed.generate(folders, port, feedinfo, function(err, xml) { | ||
if (err) return log.error(err); | ||
webserver.reloadXml(xml); | ||
}); | ||
if (req.url === '/') { | ||
res.writeHead(200, {'Content-Type': 'text/xml; charset=UTF-8'}); | ||
res.end(xml.replace(/@@HOST@@/g, (req.headers.host || cfg.site_url))); | ||
res.emit('sendStarted'); | ||
} else { | ||
var queried = url.parse(decodeURI(req.url).replace(/\.mp3$/g, '')).path.slice(1); | ||
var found = false; | ||
cfg.music_folder.forEach(function(folder, idx, ary) { | ||
if (found) return; | ||
log.info('matcher', 'Trying to find %s in %s', queried, folder); | ||
var isLastFolder = (idx === ary.length - 1); | ||
var directory = path.resolve(folder, queried); | ||
if (fs.existsSync(directory)) { | ||
found = true; | ||
streamDirectoryContent(directory, res); | ||
} else if (isLastFolder) { | ||
res.writeHead(404); | ||
res.end(); | ||
res.emit('sendStarted'); | ||
} | ||
}); | ||
} | ||
}).listen(cfg.port, function() { | ||
log.info('server', 'Server listening on port %d', cfg.port); | ||
}); | ||
|
||
/* Directory watcher part */ | ||
var regenerator = (function() { | ||
var _generate = function() { | ||
if (buildlater) { | ||
buildlater = false; | ||
build.close(); | ||
build = setTimeout(_generate, timeout); | ||
return; | ||
} | ||
log.info("feed generation", "generating feed"); | ||
generateFeed().then(function(output) { xml = output; }); | ||
buildlater = false; | ||
timeout = 5000; | ||
} | ||
|
||
var build = setTimeout(_generate, 1); | ||
var timeout = 5000; | ||
var buildlater = false; | ||
|
||
return function(filename) { | ||
if (buildlater) { | ||
return; | ||
} else if (build._idleNext !== null) { | ||
//build already queued | ||
log.info('watcher', 'Quick changes detected in filesystem, waiting before taking action'); | ||
timeout *= 2; | ||
buildlater = true; | ||
} else { | ||
log.info('watcher', '%s changed on disk, queuing RSS regeneration', filename); | ||
} | ||
build.close(); | ||
build = setTimeout(_generate, timeout); | ||
}; | ||
})(); | ||
|
||
watch(cfg.music_folder, { followSymLinks:true, maxSymLevel:10 }, regenerator); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
var http = require('http'), | ||
fs = require('fs'), | ||
path = require('path'), | ||
log = require('npmlog'), | ||
streamDirectoryContent = require('./stream.js'); | ||
|
||
var _getResourceFromPath = function(path) { | ||
return decodeURIComponent(path) //cleaning | ||
.replace(/\.mp3$/g, '') //Triming extension | ||
.replace(/^\//g, ''); //removing leading slash | ||
}; | ||
|
||
var _findResourceFullPath = function(dirs, resource) { | ||
if (typeof dirs === 'string') dirs = [dirs]; | ||
for (var i = 0; i < dirs.length; i+= 1) { | ||
var dir = dirs[i]; | ||
log.info('server', 'Trying to find %s in %s', resource, dir); | ||
var fullpath = path.resolve(dir, resource); | ||
if (fs.existsSync(fullpath)) return fullpath; | ||
} | ||
return null; | ||
}; | ||
|
||
var startServer = function(xml, folders, port, url) { | ||
var server = http.createServer(function (req, res) { | ||
res.on('sendStarted', function() { | ||
log.info( | ||
'server', '[%s] %s %s (%d)', | ||
req.connection.remoteAddress, req.method, req.url, res.statusCode | ||
); | ||
}); | ||
if (req.url === '/') { | ||
res.writeHead(200, {'Content-Type': 'text/xml; charset=UTF-8'}); | ||
res.end(xml.replace(/@@HOST@@/g, (req.headers.host || url))); | ||
return res.emit('sendStarted'); | ||
} else { | ||
var resource = _getResourceFromPath(req.url); | ||
var fullpath = _findResourceFullPath(folders, resource); | ||
|
||
if (fullpath === null) { | ||
res.writeHead(404); | ||
res.end(); | ||
return res.emit('sendStarted'); | ||
} | ||
return streamDirectoryContent(fullpath, res); | ||
} | ||
}).listen(port, function() { | ||
log.info('server', 'Server listening on port %d', port); | ||
}); | ||
server.reloadXml = function(new_xml) { | ||
log.info('server', 'Received new XML'); | ||
xml = new_xml; | ||
}; | ||
return server; | ||
}; | ||
|
||
exports.startServer = startServer; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
var watch = require('node-watch'), | ||
log = require('npmlog'); | ||
var regenerator = function(cb) { | ||
var _generate = function() { | ||
if (buildlater) { | ||
buildlater = false; | ||
build.close(); | ||
build = setTimeout(_generate, timeout); | ||
return; | ||
} | ||
buildlater = false; | ||
timeout = 5000; | ||
log.info("watcher", "building"); | ||
cb(); | ||
}; | ||
|
||
var build = setTimeout(_generate, 1); | ||
var timeout = 5000; | ||
var buildlater = false; | ||
|
||
return function(filename) { | ||
if (buildlater) { | ||
return; | ||
} else if (build._idleNext !== null) { | ||
//build already queued | ||
log.info('watcher', 'Quick changes detected in filesystem, waiting before taking action'); | ||
timeout *= 2; | ||
buildlater = true; | ||
} else { | ||
log.info('watcher', '%s changed on disk, queuing RSS regeneration', filename); | ||
} | ||
build.close(); | ||
build = setTimeout(_generate, timeout); | ||
}; | ||
}; | ||
|
||
var startWatching = function(folders, cb) { | ||
var opts = { followSymLinks:true, maxSymLevel:10 }; | ||
watch(folders, opts, regenerator(cb)); | ||
}; | ||
|
||
exports.startWatching = startWatching; |