diff --git a/lib/connection.js b/lib/connection.js index 7571c4e..91afc95 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -1,11 +1,12 @@ var net = require("net"); -var xml = require("./xml2json"); module.exports = function (ccg) { ccg.prototype.connected = false; var client; var disconnecting = false; + var responseCode = false; + var responseMessage = ""; var response = ""; var readyForNextCommand = true; var waitingForDoubleTerminator = false; @@ -93,11 +94,8 @@ module.exports = function (ccg) { // ccg.sendCommand // --------------- // Sends raw command to CasparCG - ccg.prototype.sendCommand = function (command, doubleTerminator, cb) { - if (!cb && typeof(doubleTerminator) == "function") { - cb = doubleTerminator; - doubleTerminator = false; - } + ccg.prototype.sendCommand = function (command, cb) { + var self = this; if (typeof(cb) != "function") cb = false; @@ -110,13 +108,37 @@ module.exports = function (ccg) { return false; } - if (command.substr(-2) != "\r\n") command += "\r\n"; + if (command.substr(-2) == "\r\n") { + if (cb) { + cb(new Error("Invalid command")); + } + + return false; + } - commandQueue.push([command, cb || false, doubleTerminator]); + command += "\r\n"; + + commandQueue.push({cmd: command, cb: cb}); if (readyForNextCommand) { readyForNextCommand = false; - client.write(commandQueue[0][0]); + self.log("Send:",commandQueue[0].cmd.substr(0, commandQueue[0].cmd.length - 2)); + client.write(commandQueue[0].cmd); + } + }; + + var finishedCommand = function (self) { + responseCode = false; + responseMessage = ""; + response = ""; + + if (commandQueue.length > 0) { + // if there are queue commands send the next one + self.log("Send:",commandQueue[0].cmd.substr(0, commandQueue[0].cmd.length - 2)); + client.write(commandQueue[0].cmd); + } else { + // queue is empty we are ready for another command + readyForNextCommand = true; } }; @@ -124,61 +146,55 @@ module.exports = function (ccg) { return function (chunk) { response += chunk.toString(); - // check for complete response before doing anything - if ( - (commandQueue[0][2] && response.substr(-4) == "\r\n\r\n") || - (!commandQueue[0][2] && response.substr(-2) == "\r\n") - ) { - // response is complete remove command from queue - var item = commandQueue.shift(); - var cb = item[1]; - - // remove the terminator - while (response.substr(-2) == "\r\n") { - response = response.substr(0, response.length - 2); - } + if (!responseCode) { + responseCode = parseInt(response.substr(0, 3), 10); + self.log("Response Code:", responseCode); + } - var responseMessage = response.substr(0, response.indexOf("\r\n")); + // if no \r\n then wait for more data + if (response.substr(-2) != "\r\n") return; - if (responseMessage == "") responseMessage = response; + if (responseMessage === "") { + responseMessage = response.substr(0, response.indexOf("\r\n")); + response = response.substr(responseMessage.length + 2); + } - self.log(responseMessage); + // 200 needs \r\n\r\n + if (responseCode == 200 && response.substr(-4) != "\r\n\r\n") return; - // check for error code - if (responseMessage.substr(0, 1) != "2") { - // callback with error - if (cb) { - cb(new Error(response)); - } - } else { - if (cb) { - // remove response code and message from response data - response = response.substr(responseMessage.length + 2); - - // check for XML response - if (response.substr(0, 1) == "<") { - response = response.substr(response.indexOf("\n") + 1); - xml(response, cb); - } else { - if (response == "") { - cb(); - } else { - response = response.split("\r\n"); - cb(null, response); - } - } - } + // strip trailing \r\n + while (response.substr(-2) == "\r\n") { + response = response.substr(0, response.length - 2); + } + + // response is complete remove command from queue + var item = commandQueue.shift(); + var cb = item.cb || false; + + // check for error + if ( + (responseCode >= 400) && + (responseCode > 600) + ) { + // callback with error + if (cb) { + cb(new Error(responseMessage)); } - response = ""; - if (commandQueue.length > 0) { - // if there are queue commands send the next one - client.write(commandQueue[0][0]); + finishedCommand(self); + + return; + } + + if (cb) { + if (response !== "") { + cb(null, response); } else { - // queue is empty we are ready for another command - readyForNextCommand = true; + cb(null); } } + + finishedCommand(self); }; }; }; diff --git a/lib/query.js b/lib/query.js index 2b97a17..35f8aa3 100644 --- a/lib/query.js +++ b/lib/query.js @@ -1,3 +1,5 @@ +var xml = require("./xml2json"); + module.exports = function (ccg) { // ccg.getMediaFiles // --- @@ -13,12 +15,14 @@ module.exports = function (ccg) { return; } - self.sendCommand("CLS", true, function (err, files) { + self.sendCommand("CLS", function (err, data) { if (err) { cb(err); return; } + var files = data.split("\r\n"); + var out = []; for (var index in files) { @@ -51,7 +55,7 @@ module.exports = function (ccg) { ccg.prototype.getMediaFileInfo = function (filename, cb) { var self = this; - if (typeof(folder) != "string") { + if (typeof(filename) != "string") { self.log("Invalid arguments"); return; } @@ -62,12 +66,14 @@ module.exports = function (ccg) { return; } - self.sendCommand("CINF \"" + filename + "\"", function (err, files) { + self.sendCommand("CINF \"" + filename + "\"", function (err, data) { if (err) { if (cb) cb(err); return; } + var files = data.split("\r\n"); + var out = []; for (var index in files) { @@ -92,7 +98,7 @@ module.exports = function (ccg) { }; // --- - // ccg.getMediaFiles + // ccg.getTemplates // --- // Returns info about all available templates // Returns info about all available templates @@ -116,12 +122,14 @@ module.exports = function (ccg) { if (folder) command += " " + folder; - self.sendCommand(command, function (err, files) { + self.sendCommand(command, function (err, data) { if (err) { cb(err); return; } + var files = data.split("\r\n"); + var out = []; for (var index in files) { @@ -166,6 +174,20 @@ module.exports = function (ccg) { if (channel) command += " " + channel; - self.sendCommand(command, cb); + self.sendCommand(command, function (err, data) { + if (err) { + cb(err); + return; + } + + console.log(typeof(data)); + + if (data.substr(0, 1) == "<") { + xml(data, cb); + } else { + data = data.split("\r\n"); + cb(null, data); + } + }); }; }; diff --git a/lib/xml2json.js b/lib/xml2json.js index d07c117..5114a2e 100644 --- a/lib/xml2json.js +++ b/lib/xml2json.js @@ -39,7 +39,7 @@ module.exports = function (xml, cb) { object[path[index]].push({}); } } - }; + } // helper function to set the value of a path function setValueForPath(object, path, value, index) { @@ -56,7 +56,7 @@ module.exports = function (xml, cb) { // found the object so set its value object[path[index]] = value; } - }; + } parser.onerror = function (err) { // should pass this to the callback diff --git a/test.js b/test.js index 75ce391..df4592b 100644 --- a/test.js +++ b/test.js @@ -7,18 +7,37 @@ ccg = new CasparCG({ }); ccg.connect(function () { + ccg.play("1-1", "AMB"); + + ccg.getMediaFiles(function (err, serverInfo) { + console.log("getMediaFiles", serverInfo); + }); + + ccg.getMediaFileInfo("AMB", function (err, serverInfo) { + console.log("getMediaFileInfo", serverInfo); + }); + + ccg.getTemplates(function (err, serverInfo) { + console.log("info", serverInfo); + }); + ccg.info(function (err, serverInfo) { - console.log(serverInfo); + console.log("info", serverInfo); }); - ccg.play("1-1", "AMB"); + ccg.info("1", function (err, serverInfo) { + console.log("info 1", serverInfo); + }); + + ccg.info("1-1", function (err, serverInfo) { + console.log("info 1-1", serverInfo); + }); setTimeout(function () { ccg.clear("1"); + }, 1 * 1000); + + setTimeout(function () { ccg.disconnect(); }, 5 * 1000); }); - -ccg.on("connected", function () { - console.log("Connected"); -}); \ No newline at end of file