battery-minus

Pebble activity tracker that records battery events
git clone https://git.instinctive.eu/battery-minus.git
Log | Files | Refs | README | LICENSE

app.js (7483B)


      1 /*
      2  * Copyright (c) 2016, Natacha Porté
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 var cfg_endpoint = null;
     18 var cfg_data_field = null;
     19 var cfg_sign_algo = "";
     20 var cfg_sign_field = "";
     21 var cfg_sign_field_format = "";
     22 var cfg_sign_key = "";
     23 var cfg_sign_key_format = "";
     24 var cfg_extra_fields = [];
     25 var cfg_wakeup_time = -1;
     26 
     27 var to_send = [];
     28 var senders = [new XMLHttpRequest(), new XMLHttpRequest()];
     29 var i_sender = 1;
     30 var jsSHA = require("sha");
     31 
     32 function sendPayload(payload) {
     33    var data = new FormData();
     34    data.append(cfg_data_field, payload);
     35 
     36    if (cfg_sign_field) {
     37       var sha = new jsSHA(cfg_sign_algo, "TEXT");
     38       sha.setHMACKey(cfg_sign_key, cfg_sign_key_format);
     39       sha.update(payload);
     40       data.append(cfg_sign_field, sha.getHMAC(cfg_sign_field_format));
     41    }
     42 
     43    if (cfg_extra_fields.length > 0) {
     44       for (var i = 0; i < cfg_extra_fields.length; i += 1) {
     45          var decoded = decodeURIComponent(cfg_extra_fields[i]).split("=");
     46          var name = decoded.shift();
     47          var value = decoded.join("=");
     48          data.append(name, value);
     49       }
     50    }
     51 
     52    i_sender = 1 - i_sender;
     53    senders[i_sender].open("POST", cfg_endpoint, true);
     54    senders[i_sender].send(data);
     55 }
     56 
     57 function sendHead() {
     58    if (to_send.length < 1) return;
     59    sendPayload(to_send[0].split(";")[1]);
     60 }
     61 
     62 function enqueue(key, line) {
     63    to_send.push(key + ";" + line);
     64    localStorage.setItem("toSend", to_send.join("|"));
     65    localStorage.setItem("lastSent", key);
     66    if (to_send.length === 1) {
     67       sendHead();
     68    }
     69 }
     70 
     71 function uploadDone() {
     72    var sent_key = to_send.shift().split(";")[0];
     73    localStorage.setItem("toSend", to_send.join("|"));
     74    if (to_send.length === 0) {
     75       Pebble.sendAppMessage({ "lastPosted": parseInt(sent_key, 10) });
     76    }
     77    sendHead();
     78 }
     79 
     80 function uploadError() { console.log(this.statusText); }
     81 
     82 senders[0].addEventListener("load", uploadDone);
     83 senders[0].addEventListener("error", uploadError);
     84 senders[1].addEventListener("load", uploadDone);
     85 senders[1].addEventListener("error", uploadError);
     86 
     87 Pebble.addEventListener("ready", function(e) {
     88    console.log("Battery- JS ready");
     89 
     90    var str_to_send = localStorage.getItem("toSend");
     91    to_send = str_to_send ? str_to_send.split("|") : [];
     92 
     93    var str_extra_fields = localStorage.getItem("extraFields");
     94    cfg_extra_fields = str_extra_fields ? str_extra_fields.split(",") : [];
     95 
     96    cfg_endpoint = localStorage.getItem("cfgEndpoint");
     97    cfg_data_field = localStorage.getItem("cfgDataField");
     98    cfg_sign_algo = localStorage.getItem("cfgSignAlgorithm");
     99    cfg_sign_field = localStorage.getItem("cfgSignFieldName");
    100    cfg_sign_field_format = localStorage.getItem("cfgSignFieldFormat");
    101    cfg_sign_key = localStorage.getItem("cfgSignKey");
    102    cfg_sign_key_format = localStorage.getItem("cfgSignKeyFormat");
    103    cfg_wakeup_time = parseInt(localStorage.getItem("cfgWakeupTime") || "-1", 10);
    104 
    105    if (cfg_endpoint && cfg_data_field) {
    106       Pebble.sendAppMessage({ "lastSent":
    107        parseInt(localStorage.getItem("lastSent") || "0", 10) });
    108    }
    109 
    110    if (to_send.length >= 1) {
    111       sendHead();
    112    }
    113 });
    114 
    115 Pebble.addEventListener("appmessage", function(e) {
    116    if (e.payload.dataKey && e.payload.dataLine) {
    117       enqueue(e.payload.dataKey, e.payload.dataLine);
    118    }
    119 });
    120 
    121 Pebble.addEventListener("showConfiguration", function() {
    122    var settings = "?v=1.0";
    123 
    124    if (cfg_endpoint) {
    125       settings += "&url=" + encodeURIComponent(cfg_endpoint);
    126    }
    127 
    128    if (cfg_data_field) {
    129       settings += "&data_field=" + encodeURIComponent(cfg_data_field);
    130    }
    131 
    132    if (cfg_sign_field) {
    133       settings += "&s_algo=" + encodeURIComponent(cfg_sign_algo)
    134        + "&s_field=" + encodeURIComponent(cfg_sign_field)
    135        + "&s_fieldf=" + encodeURIComponent(cfg_sign_field_format)
    136        + "&s_key=" + encodeURIComponent(cfg_sign_key)
    137        + "&s_keyf=" + encodeURIComponent(cfg_sign_key_format);
    138    }
    139 
    140    if (cfg_wakeup_time >= 0) {
    141       settings += "&wakeup=" + cfg_wakeup_time.toString(10);
    142    }
    143 
    144    if (cfg_extra_fields.length > 0) {
    145       settings += "&extra=" + cfg_extra_fields.join(",");
    146    }
    147 
    148    Pebble.openURL("https://cdn.rawgit.com/faelys/battery-minus/v1.0/config.html" + settings);
    149 });
    150 
    151 Pebble.addEventListener("webviewclosed", function(e) {
    152    var configData = JSON.parse(e.response);
    153    var wasConfigured = (cfg_endpoint && cfg_data_field);
    154 
    155    if (configData.url) {
    156       cfg_endpoint = decodeURIComponent(configData.url);
    157       localStorage.setItem("cfgEndpoint", cfg_endpoint);
    158    }
    159 
    160    if (configData.dataField) {
    161       cfg_data_field = configData.dataField;
    162       localStorage.setItem("cfgDataField", cfg_data_field);
    163    }
    164 
    165    if (configData.signAlgorithm) {
    166       cfg_sign_algo = configData.signAlgorithm;
    167       localStorage.setItem("cfgSignAlgorithm", cfg_sign_algo);
    168    }
    169 
    170    if (configData.signFieldName) {
    171       cfg_sign_field = configData.signFieldName;
    172       localStorage.setItem("cfgSignFieldName", cfg_sign_field);
    173    }
    174 
    175    if (configData.signFieldFormat) {
    176       cfg_sign_field_format = configData.signFieldFormat;
    177       localStorage.setItem("cfgSignFieldFormat", cfg_sign_field_format);
    178    }
    179 
    180    if (configData.signKey) {
    181       cfg_sign_key = decodeURIComponent(configData.signKey);
    182       localStorage.setItem("cfgSignKey", cfg_sign_key);
    183    }
    184 
    185    if (configData.signKeyFormat) {
    186       cfg_sign_key_format = configData.signKeyFormat;
    187       localStorage.setItem("cfgSignKeyFormat", cfg_sign_key_format);
    188    }
    189 
    190    if (configData.wakeupTime !== null) {
    191       console.log("Received wakeupTime \"" + configData.wakeupTime + "\"");
    192       var wakeupComponents = configData.wakeupTime.split(":");
    193       if (wakeupComponents.length === 2) {
    194          var wakeupH = parseInt(wakeupComponents[0], 10);
    195          var wakeupM = parseInt(wakeupComponents[1], 10);
    196          if (wakeupH >= 0 && wakeupH < 24 && wakeupM >= 0 && wakeupM < 60) {
    197             cfg_wakeup_time = wakeupH * 60 + wakeupM;
    198             localStorage.setItem("cfgWakeupTime", cfg_wakeup_time);
    199             Pebble.sendAppMessage({ "cfgWakeupTime": cfg_wakeup_time });
    200          }
    201          else
    202             console.log("Invalid wakeupTime \"" + configData.wakeupTime + "\"");
    203       }
    204       else
    205          console.log("Invalid wakeupTime \"" + configData.wakeupTime + "\"");
    206    }
    207 
    208    if (configData.extraFields !== null) {
    209       cfg_extra_fields = configData.extraFields
    210        ? configData.extraFields.split(",") : [];
    211       localStorage.setItem("extraFields", cfg_extra_fields.join(","));
    212    }
    213 
    214    if (configData.resend) {
    215       senders[0].abort();
    216       senders[1].abort();
    217       localStorage.setItem("toSend", "");
    218       localStorage.setItem("lastSent", "0");
    219       to_send = [];
    220       wasConfigured = false;
    221    }
    222 
    223    if (!wasConfigured && cfg_endpoint && cfg_data_field) {
    224       Pebble.sendAppMessage({ "lastSent": 0 });
    225    }
    226 });