Airbreaks-Low-Power/Programming/Javascript/node_modules/plotly/index.js
2023-12-19 18:30:36 -06:00

325 lines
8.1 KiB
JavaScript

'use strict';
var https = require('https');
var http = require('http');
var jsonStatus = require('./statusmsgs.json');
var url = require('url');
module.exports = Plotly;
function Plotly(username,apiKey) {
if (!(this instanceof Plotly)) return new Plotly(username,apiKey);
var opts = {};
if (typeof username === 'object') {
opts = username;
this.username = opts.username;
this.apiKey = opts.apiKey;
this.host = opts.host || 'plot.ly';
this.port = opts.port || 443;
} else {
this.username = username;
this.apiKey = apiKey;
this.host = 'plot.ly';
this.port = 443;
}
this.streamHost = '';
this.version='1.0.4';
this.platform='nodejs';
this.origin='plot';
}
Plotly.prototype.plot = function(data, graphOptions, callback) {
var self = this;
if (!callback) { callback = function() {}; }
// allow users to just pass in an object for the data, data = {x:[],y:[]}
if (!Array.isArray(data)) data = [data];
var urlencoded = '';
var pack = {
'platform': self.platform,
'version': self.version,
'args': JSON.stringify(data),
'kwargs': JSON.stringify(graphOptions),
'un': self.username,
'key': self.apiKey,
'origin': self.origin
};
for (var key in pack) {
urlencoded += key + '=' + pack[key] + '&';
}
// trim off last ambersand
urlencoded = new Buffer(urlencoded.substring(0, urlencoded.length - 1), 'utf8');
var options = {
host: self.host,
port: self.port,
path: '/clientresp',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': urlencoded.length
},
withCredentials: false
};
var req = https.request(options, function (res) {
parseRes(res, function (err, body) {
/* Try to parse the response */
try {
body = JSON.parse(body);
} catch (e) {
callback(e);
}
if ( body['stream-status'] != undefined) {
self.streamHost = url.parse(body['stream-host']).hostname;
}
if ( body.error.length > 0 ) {
var error = new Error(body.error);
error.body = body;
error.statusCode = res.statusCode;
callback(error);
} else {
callback(null, {
streamstatus : body['stream-status'],
url: body.url,
message: body.message,
warning: body.warning,
filename: body.filename,
error: body.error
});
}
});
});
req.on('error', function(err) {
callback(err);
});
req.write(urlencoded);
req.end();
};
Plotly.prototype.stream = function(token, callback) {
var self = this;
var opts = {};
if (typeof token === 'object') {
opts = token;
token = opts.token;
var host = opts.streamHost || self.streamHost;
var port = opts.port || 80;
}
var options = {
host: host || self.streamHost || 'stream.plot.ly',
port: port || 80,
path: '/',
method: 'POST',
agent: false,
headers: { 'plotly-streamtoken' : token }
};
if (!callback) { callback = function() {}; }
var stream = http.request(options, function (res) {
var message = jsonStatus[res.statusCode];
if (res.statusCode !== 200) {
var error = new Error(message);
error.statusCode = res.statusCode;
callback(error);
} else {
callback(null, {msg : message, statusCode: res.statusCode});
}
});
stream.on('error', function (err) {
callback(err);
});
if (stream.setTimeout) stream.setTimeout(Math.pow(2, 32) * 1000);
return stream;
};
Plotly.prototype.getFigure = function (fileOwner, fileId, callback) {
var self = this;
if (!callback) { callback = function() {}; }
var headers = {
'plotly-username': this.username,
'plotly-apikey': this.apiKey,
'plotly-version': this.version,
'plotly-platform': this.platform
};
var resource = '/apigetfile/'+fileOwner+'/'+fileId;
var options = {
host: self.host,
path: resource,
port: self.port,
headers: headers,
method: 'GET'
};
var req = https.get(options, function (res) {
parseRes(res, function (err, body) {
/* Try to parse the response */
try {
body = JSON.parse(body);
} catch (e) {
callback(e);
}
if (body.error) {
callback(body.error);
}
else {
var figure = body.payload.figure;
callback(null, figure);
}
});
});
req.on('error', function (err) {
callback(err);
});
req.end();
};
Plotly.prototype.getImage = function (figure, opts, callback) {
callback = callback || function () {};
if (!figure) return new Error('no figure provided!');
var self = this;
var payload = JSON.stringify({
figure: figure,
format: opts.format || 'png',
width: opts.width || 700,
height: opts.height || 500
});
var headers = {
'plotly-username': self.username,
'plotly-apikey': self.apiKey,
'plotly-version': self.version,
'plotly-platform': self.platform,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': payload.length
};
var options = {
hostname: self.host,
path : '/apigenimage/',
port: self.port,
headers: headers,
method: 'POST',
agent: false
};
function handleResponse(res) {
if (res.statusCode !== 200) {
var error = new Error('Bad response status code ' + res.statusCode);
error.msg = res.body;
return callback(error, null);
}
callback(null, res);
}
var req = https.request(options, handleResponse);
req.on('error', function (err) {
callback(err);
});
req.write(payload);
req.end();
};
Plotly.prototype.deletePlot = function (fid, callback) {
if (!callback) callback = function () {};
var self = this;
// Create the base64 authstring from buffer
var encodedAPIAuth = new Buffer(this.username + ':' + this.apiKey).toString('base64');
var options = {
host: 'api.plot.ly',
port: this.port,
path: '/v2/files/' + this.username + ':' + fid + '/trash',
method: 'POST',
agent: false,
withCredentials: true,
headers: {
'Plotly-Client-Platform': 'nodejs ' + this.version,
'authorization': 'Basic ' + encodedAPIAuth
}
};
var req = https.request(options, function (res) {
parseRes(res, function (err, body) {
if (res.statusCode === 200) {
callback(null, body);
} else {
var errObj = {
statusCode: res.statusCode,
err: body,
statusMessage: res.statusMessage
};
callback(errObj); // Pass out the error message from the backend
}
});
});
req.on('error', function (err) {
callback(err);
});
req.end();
};
// response parse helper fn
function parseRes (res, cb) {
var body = '';
if ('setEncoding' in res) res.setEncoding('utf-8');
res.on('data', function (data) {
body += data;
if (body.length > 1e10) {
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQ
res.connection.destroy();
res.writeHead(413, {'Content-Type': 'text/plain'});
res.end('req body too large');
return cb(new Error('body overflow'));
}
});
res.on('end', function () {
cb(null, body);
});
}