/*
* Copyright (c) 2016, Natacha Porté
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var cfg_endpoint = null;
var cfg_data_field = null;
var cfg_bundle_max = 1;
var cfg_bundle_separator = "\r\n";
var cfg_sign_algo = "";
var cfg_sign_field = "";
var cfg_sign_field_format = "";
var cfg_sign_key = "";
var cfg_sign_key_format = "";
var to_send = [];
var senders = [new XMLHttpRequest(), new XMLHttpRequest()];
var i_sender = 1;
var bundle_size = 0;
function sendPayload(payload) {
var data = new FormData();
data.append(cfg_data_field, payload);
i_sender = 1 - i_sender;
senders[i_sender].open("POST", cfg_endpoint, true);
senders[i_sender].send(data);
}
function sendHead() {
if (to_send.length < 1) return;
bundle_size = 0;
var payload = [];
while (bundle_size < cfg_bundle_max && bundle_size < to_send.length) {
payload.push(to_send[bundle_size].split(";")[1]);
bundle_size += 1;
}
sendPayload(payload.join(cfg_bundle_separator));
}
function enqueue(key, line) {
to_send.push(key + ";" + line);
localStorage.setItem("toSend", to_send.join("|"));
localStorage.setItem("lastSent", key);
if (to_send.length === 1) {
Pebble.sendAppMessage({ "uploadStart": parseInt(key, 10) });
sendHead();
}
}
function uploadDone() {
if (bundle_size > 1) {
to_send.splice(0, bundle_size - 1);
}
var sent_key = to_send.shift().split(";")[0];
localStorage.setItem("toSend", to_send.join("|"));
Pebble.sendAppMessage({ "uploadDone": parseInt(sent_key, 10) });
sendHead();
}
function uploadError() { console.log(this.statusText); }
senders[0].addEventListener("load", uploadDone);
senders[0].addEventListener("error", uploadError);
senders[1].addEventListener("load", uploadDone);
senders[1].addEventListener("error", uploadError);
Pebble.addEventListener("ready", function() {
console.log("Health Export PebbleKit JS ready!");
var str_to_send = localStorage.getItem("toSend");
to_send = str_to_send ? str_to_send.split("|") : [];
cfg_endpoint = localStorage.getItem("cfgEndpoint");
cfg_data_field = localStorage.getItem("cfgDataField");
cfg_bundle_max = parseInt(localStorage.getItem("cfgBundleMax") || "1", 10);
cfg_bundle_separator = localStorage.getItem("cfgBundleSeparator");
cfg_sign_algo = localStorage.getItem("cfgSignAlgorithm");
cfg_sign_field = localStorage.getItem("cfgSignFieldName");
cfg_sign_field_format = localStorage.getItem("cfgSignFieldFormat");
cfg_sign_key = localStorage.getItem("cfgSignKey");
cfg_sign_key_format = localStorage.getItem("cfgSignKeyFormat");
if (!(cfg_bundle_max >= 1)) cfg_bundle_max = 1;
var msg = {};
if (cfg_endpoint && cfg_data_field) {
msg.lastSent = parseInt(localStorage.getItem("lastSent") || "0", 10);
} else {
msg.modalMessage = "Not configured";
}
if (to_send.length >= 1) {
msg.uploadStart = parseInt(to_send[0].split(";")[0]);
}
Pebble.sendAppMessage(msg);
if (to_send.length >= 1) {
sendHead();
}
});
Pebble.addEventListener("appmessage", function(e) {
if (e.payload.dataKey && e.payload.dataLine) {
enqueue(e.payload.dataKey, e.payload.dataLine);
}
});
Pebble.addEventListener("showConfiguration", function() {
var settings = "?v=1.0";
if (cfg_endpoint) {
settings += "&url=" + encodeURIComponent(cfg_endpoint);
}
if (cfg_data_field) {
settings += "&data_field=" + encodeURIComponent(cfg_data_field);
}
if (cfg_bundle_max) {
settings += "&bundle_max=" + encodeURIComponent(cfg_bundle_max);
}
if (cfg_bundle_separator) {
settings += "&bundle_sep=" + encodeURIComponent(cfg_bundle_separator);
}
if (cfg_sign_field) {
settings += "&s_algo=" + encodeURIComponent(cfg_sign_algo)
+ "&s_field=" + encodeURIComponent(cfg_sign_field)
+ "&s_fieldf=" + encodeURIComponent(cfg_sign_field_format)
+ "&s_key=" + encodeURIComponent(cfg_sign_key)
+ "&s_keyf=" + encodeURIComponent(cfg_sign_key_format);
}
Pebble.openURL("https://cdn.rawgit.com/faelys/pebble-health-export/v1.0/config.html" + settings);
});
Pebble.addEventListener("webviewclosed", function(e) {
var configData = JSON.parse(decodeURIComponent(e.response));
var wasConfigured = (cfg_endpoint && cfg_data_field);
if (configData.url) {
cfg_endpoint = configData.url;
localStorage.setItem("cfgEndpoint", cfg_endpoint);
}
if (configData.dataField) {
cfg_data_field = configData.dataField;
localStorage.setItem("cfgDataField", cfg_data_field);
}
if (configData.bundleMax) {
cfg_bundle_max = parseInt(configData.bundleMax, 10);
if (!(cfg_bundle_max >= 1)) cfg_bundle_max = 1;
localStorage.setItem("cfgBundleMax", cfg_bundle_max);
}
if (configData.bundleSeparator) {
cfg_bundle_separator = decodeURIComponent(configData.bundleSeparator);
localStorage.setItem("cfgBundleSeparator", cfg_bundle_separator);
}
if (configData.signAlgorithm) {
cfg_sign_algo = configData.signAlgorithm;
localStorage.setItem("cfgSignAlgorithm", cfg_sign_algo);
}
if (configData.signFieldName) {
cfg_sign_field = configData.signFieldName;
localStorage.setItem("cfgSignFieldName", cfg_sign_field);
}
if (configData.signFieldFormat) {
cfg_sign_field_format = configData.signFieldFormat;
localStorage.setItem("cfgSignFieldFormat", cfg_sign_field_format);
}
if (configData.signKey) {
cfg_sign_key = configData.signKey;
localStorage.setItem("cfgSignKey", cfg_sign_key);
}
if (configData.signKeyFormat) {
cfg_sign_key_format = configData.signKeyFormat;
localStorage.setItem("cfgSignKeyFormat", cfg_sign_key_format);
}
console.log(cfg_sign_field ? "Signature enabled" : "Signature disabled");
if (configData.resend) {
senders[0].abort();
senders[1].abort();
localStorage.setItem("toSend", "");
localStorage.setItem("lastSent", "0");
to_send = [];
wasConfigured = false;
}
if (!wasConfigured && cfg_endpoint && cfg_data_field) {
Pebble.sendAppMessage({ "lastSent": 0 });
}
});