Commit e43eca1f authored by Alain Takoudjou's avatar Alain Takoudjou Committed by Alain Takoudjou

[officejs_monitoring] Some performances improvement, speed up hosting...

[officejs_monitoring] Some performances improvement, speed up hosting subscription list page rendering

Speed up display of hosting subscription list by reducing the amount of queries.
If a document is not synced (due to an error) change the status of that document to WARNING so that monitor will
tell when instances/servers are offline.
parent 1ecc8cca
......@@ -328,7 +328,7 @@ NETWORK:\n
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.22192.23748.64392</string> </value>
<value> <string>961.46782.15224.10001</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -346,7 +346,7 @@ NETWORK:\n
</tuple>
<state>
<tuple>
<float>1502462901.33</float>
<float>1503935899.97</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -83,6 +83,9 @@ html.ui-mobile .ui-grid-container.ui-responsive > ul > li, html.ui-mobile .ui-gr
.ui-text{
padding: 0 10px;
}
.ui-text-pre {
white-space: pre-wrap;
}
.ui-text-left {text-align: left;}
.ui-text-right {text-align: right;}
.ui-text-center {
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21883.33309.38348</string> </value>
<value> <string>961.46334.51033.4727</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502455104.39</float>
<float>1504086678.92</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,6 +14,17 @@
<script id="login-toltip-template" type="text/x-handlebars-template">
</script>
<script id="monitor-parameters-template" type="text/x-handlebars-template">
{{#each parameter_list}}
<span class="label-text">{{title}}:</span>
{{#if key}}
<input type="text" name="{{key}}" placeholder="{{title}}" value="{{value}}" data-mini="true">
{{else}}
<input type="text" name="{{key}}" placeholder="{{title}}" value="{{value}}" data-mini="true" disabled="disabled">
{{/if}}
{{/each}}
</script>
<!-- magnific-popup -->
<script src="jquery.magnific-popup.min.js" type="text/javascript"></script>
<!-- custom script -->
......@@ -22,7 +33,6 @@
</head>
<body>
<div data-gadget-url="gadget_monitoring_jio.html" data-gadget-scope="jio_gadget" data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_monitoring_login_widget.html" data-gadget-scope="login_gadget" data-gadget-sandbox="public"></div>
<div class="white-popup mfp-hide">
<div class="ui-promise-title"><h2 style="font-size: 1.1em;"></h2></div>
<form>
......
......@@ -237,7 +237,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.48450.25809.9642</string> </value>
<value> <string>961.40703.61920.55040</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -255,7 +255,7 @@
</tuple>
<state>
<tuple>
<float>1457629718.71</float>
<float>1503583997.49</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -5,26 +5,9 @@
var gadget_klass = rJS(window),
templater = gadget_klass.__template_element,
hashCode = new Rusha().digestFromString;
/*function getHtmlFromJson(parameter_list) {
var i,
html_content = '';
for (i = 0; i < parameter_list.length; i += 1) {
html_content += '<span class="label-text">' + parameter_list[i].title + ':</span>\n';
if (parameter_list[i].key) {
html_content += '<input type="text" name="' + parameter_list[i].key +
'" placeholder="' + parameter_list[i].title + '" value="' +
parameter_list[i].value +'" data-mini="true">\n';
} else {
html_content += '<input type="text" name="' + parameter_list[i].key +
'" placeholder="' + parameter_list[i].title + '" value="'+
parameter_list[i].value +'" data-mini="true" disabled="disabled">\n';
}
}
return html_content;
}
parameters_widget_template = Handlebars.compile(
templater.getElementById("monitor-parameters-template").innerHTML
);
function getFormDataList(formElement, parameter_list) {
var i,
......@@ -34,47 +17,24 @@
if (parameter_list[i].key) {
// Editable fields
if (formElement.querySelector('input[name="' + parameter_list[i].key + '"]').value !== undefined) {
formData_list[i].value = formElement.querySelector('input[name="' + parameter_list[i].key + '"]').value;
formData_list[i].value = formElement.querySelector('input[name="' +
parameter_list[i].key + '"]').value;
}
}
}
return formData_list;
}
function saveDocument(gadget, jio_document) {
function saveDocument(gadget, document_id, jio_document) {
// Authenticate before save
return gadget.props.login_gadget.getUrlInfo(
hashCode(gadget.props.options.url)
)
.push(function (cred) {
var url = gadget.props.options.url;
if (gadget.props.options.path) {
url += (url.endsWith('/') ? '':'/') + gadget.props.options.path;
}
if (cred === undefined) {
cred = {};
}
gadget.props.jio_gadget.createJio({
type: "query",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
type: "dav",
url: url,
basic_login: cred.hash
}
}
}, false);
return gadget.props.jio_gadget.put(gadget.props.options.key, jio_document);
})
return gadget.props.jio_gadget.put(document_id, jio_document)
.push(function (result) {
return {status: 'OK'};
}, function (error) {
console.log(error);
return {status: 'ERROR', code: error.target.status};
});
}*/
}
gadget_klass
.ready(function (g) {
......@@ -91,34 +51,40 @@
gadget.props.jio_gadget = jio_gadget;
});
})
.ready(function (gadget) {
return gadget.getDeclaredGadget("login_gadget")
.push(function (login_gadget) {
gadget.props.login_gadget = login_gadget;
});
})
.declareMethod("render", function (options) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
gadget.props.jio_gadget.createJio({
type: "query",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
type: "dav",
url: options.url,
basic_login: options.basic_login
}
}
});
gadget.props.options = options;
return gadget.props.deferred.resolve();
});
})
.declareMethod("popupEdit", function (options, updateMethod) {
var gadget = this,
title = 'Edit ' + (options.title || 'Monitoring Parameters'),
title = 'Edit - ' + options.title,
html_form = '';
gadget.props.options = options;
/*html_form = getHtmlFromJson(options.parameters || []);
html_form = parameters_widget_template({
parameter_list: options.parameters || []
});
gadget.props.element.querySelector('.form-controlgroup')
.innerHTML = html_form;
gadget.props.element.querySelector('.ui-promise-title h2')
.innerHTML = title;*/
.textContent = title;
return new RSVP.Queue()
/*.push(function () {
.push(function () {
return $.magnificPopup.open({
items: {
src: '.white-popup',
......@@ -147,23 +113,32 @@
'click',
false,
function (evt) {
var data = getFormDataList(document.querySelector('.mfp-content form'), options.parameters);
var data = getFormDataList(
document.querySelector('.mfp-content form'),
options.parameters);
return new RSVP.Queue()
.push(function () {
$(document.querySelector('.mfp-content spinner')).toggleClass('ui-content-hidden');
return RSVP.all([saveDocument(gadget, data)]);
$(document.querySelector('.mfp-content spinner'))
.toggleClass('ui-content-hidden');
return RSVP.all([saveDocument(
gadget,
options.document_id,
data
)]);
})
.push(function (result) {
if (result[0].status === 'ERROR') {
document.querySelector('.mfp-content .ui-text-error')
.innerHTML = 'ERROR ' + result[0].code + ': Failed to save your document! ' +
.innerHTML = 'ERROR ' + result[0].code +
': Failed to save your document! ' +
"Parameters cannot be saved in Offline mode.";
} else {
$.magnificPopup.close();
return updateMethod(data);}
})
.push(function () {
$(document.querySelector('.mfp-content spinner')).toggleClass('ui-content-hidden');
$(document.querySelector('.mfp-content spinner'))
.toggleClass('ui-content-hidden');
});
}
));
......@@ -176,7 +151,7 @@
}
}
});
})*/
})
.push(function () {
return gadget.props.deferred.resolve();
});
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21935.10239.63812</string> </value>
<value> <string>961.40921.12598.30395</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502457634.68</float>
<float>1503585066.29</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, Handlebars, Rusha */
/*global window, rJS, Handlebars */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, Handlebars, Rusha) {
(function (window, rJS, Handlebars) {
"use strict";
var gadget_klass = rJS(window),
......@@ -8,65 +8,80 @@
hosting_widget_template = Handlebars.compile(
templater.getElementById("template-hostings-list").innerHTML
),
rusha = new Rusha();
);
function generateHash(str) {
return rusha.digestFromString(str);
}
function getHostingStatus(gadget, id) {
function getHostingData(gadget) {
// optimized way to fetch hosting subscription list
var hosting_dict = {},
instance_dict = {};
return gadget.jio_allDocs({
query: '(portal_type:"opml-outline") AND (parent_id:"' + id + '")'
})
.push(function (ouline_list) {
var j,
promise_list = [];
for (j = 0; j < ouline_list.data.total_rows; j += 1) {
// fetch all instance info to build hosting status
promise_list.push(
gadget.jio_allDocs({
select_list: ["status", "date"],
query: '(portal_type:"global") AND (parent_id:"' +
ouline_list.data.rows[j].id + '")'
})
);
select_list: ["basic_login", "url", "title"],
query: '(portal_type:"opml") AND (active:true)',
sort_on: [["title", "descending"]]
})
.push(function (result) {
var i;
for (i = 0; i < result.data.total_rows; i += 1) {
hosting_dict[result.data.rows[i].id] = {
url: result.data.rows[i].value.url,
basic_login: result.data.rows[i].value.basic_login,
status: "WARNING",
date: 'Not Synchronized',
title: result.data.rows[i].value.title,
amount: 0
};
}
return RSVP.all(promise_list);
return gadget.jio_allDocs({
query: '(portal_type:"opml-outline")',
select_list: [
"parent_url"
]
});
})
.push(function (result_list) {
var i,
j,
status = "OK",
warning = "",
date = 'Not Synchronized';
for (i = 0; i < result_list.length; i += 1) {
for (j = 0; j < result_list[i].data.total_rows; j += 1) {
if (warning !== "" &&
result_list[i].data.rows[j].value.status === "WARNING") {
warning = "WARNING";
}
if (status !== "ERROR" && status !== "WARNING" &&
result_list[i].data.rows[j].value.status === "ERROR") {
// continue and only change the status if we found Warning === state inconsistent
status = result_list[i].data.rows[j].value.status;
date = result_list[i].data.rows[j].value.date;
} else {
date = result_list[i].data.rows[j].value.date;
}
.push(function (result) {
var i;
for (i = 0; i <result.data.total_rows; i += 1) {
if (hosting_dict.hasOwnProperty(result.data.rows[i].value.parent_url)) {
instance_dict[result.data.rows[i].id] = {
parent_id: result.data.rows[i].value.parent_url
};
}
}
return gadget.jio_allDocs({
query: '(portal_type:"global")',
select_list: [
"status",
"parent_id",
"date"
]
});
})
.push(function (result) {
var i;
for (i = 0; i < result.data.total_rows; i += 1) {
if (instance_dict.hasOwnProperty(result.data.rows[i].value.parent_id)) {
instance_dict[result.data.rows[i].value.parent_id].date =
result.data.rows[i].value.date;
instance_dict[result.data.rows[i].value.parent_id].status =
result.data.rows[i].value.status;
}
}
if (date === 'Not Synchronized') {
status = "WARNING";
})
.push(function () {
//build hosting subscription data
var key,
item;
for (key in instance_dict) {
if (instance_dict.hasOwnProperty(key)) {
item = hosting_dict[instance_dict[key].parent_id];
item.amount += 1;
if (item.status !== "ERROR") {
item.status = instance_dict[key].status;
}
item.date = instance_dict[key].date;
}
}
return {
id: id,
status: warning || status,
amount: result_list.length,
date: date
};
return gadget.changeState({opml_dict: hosting_dict});
});
}
......@@ -92,42 +107,7 @@
title: 'Monitoring Hosting Subscriptions'
})
.push(function () {
return gadget.jio_allDocs({
select_list: ["basic_login", "url", "title"],
query: '(portal_type:"opml") AND (active:true)',
sort_on: [["title", "descending"]]
});
})
.push(function (opml_result) {
var i,
opml_dict = {},
promise_list = [],
id;
for (i = 0; i < opml_result.data.total_rows; i += 1) {
id = generateHash(opml_result.data.rows[i].value.url);
opml_dict[id] = {
url: opml_result.data.rows[i].value.url,
basic_login: opml_result.data.rows[i].value.basic_login,
status: "WARNING",
date: 'Not Synchronized',
title: opml_result.data.rows[i].value.title,
amount: 0
};
promise_list.push(getHostingStatus(gadget, id));
}
return new RSVP.Queue()
.push(function () {
return RSVP.all(promise_list);
})
.push(function (status_list) {
var i;
for (i = 0; i < status_list.length; i += 1) {
opml_dict[status_list[i].id].status = status_list[i].status;
opml_dict[status_list[i].id].date = status_list[i].date;
opml_dict[status_list[i].id].amount = status_list[i].amount;
}
return gadget.changeState({opml_dict: opml_dict});
});
return getHostingData(gadget);
})
.push(function () {
var content,
......@@ -203,4 +183,4 @@
});
}(window, rJS, Handlebars, Rusha));
\ No newline at end of file
}(window, rJS, Handlebars));
\ No newline at end of file
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21883.33309.38348</string> </value>
<value> <string>961.36732.50199.26692</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502445069.07</float>
<float>1503333754.52</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -113,9 +113,7 @@
{{/if}}
<td class="ui-text-center">
{{#if key}}
<!--<a rel="{{../index}}" class="prop-edit" title='Edit this value'><i class="fa fa-pencil"></i></a>-->
<!-- disable edit for now -->
<a><span class="ui-text-desabled" title='Edit this value'><i class="fa fa-pencil"></i></span></a>
<a rel="{{../index}}" class="prop-edit" title='Edit this value'><i class="fa fa-pencil"></i></a>
{{else}}
<a><span class="ui-text-desabled" title='Edit this value'><i class="fa fa-pencil"></i></span></a>
{{/if}}
......@@ -125,7 +123,7 @@
</table>
{{/if}}
{{/each}}
<div class="alert alert-info ui-content-hidden">Your Changes can take a few minutes to appear in this screen!</div>
<div class="alert alert-info ui-content-hidden">Your changes will be persistent in this screen after the next sync!</div>
{{else}}
<h2>No parameters.</h2>
{{/if}}
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.20822.44689.64102</string> </value>
<value> <string>961.40879.58115.22357</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -264,7 +264,7 @@
</tuple>
<state>
<tuple>
<float>1502430987.78</float>
<float>1503583096.3</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -19,10 +19,20 @@
}
function getInstanceDict(gadget, monitor_dict) {
var private_url = monitor_dict._links.private_url.href.replace("jio_private", "private"),
public_url = monitor_dict._links.public_url.href.replace("jio_public", "public"),
var private_url = monitor_dict._links.private_url.href
.replace("jio_private", "private"),
public_url = monitor_dict._links.public_url.href
.replace("jio_public", "public"),
pass_url = "https://" + atob(gadget.state.opml.basic_login) +
"@" + private_url.split("//")[1];
"@" + private_url.split("//")[1],
i;
for (i = 0; i < monitor_dict.parameters.length; i += 1) {
if (monitor_dict.parameters[i].key === "monitor-password") {
// disabled edit of monitor password from here!!
monitor_dict.parameters[i].key = "";
}
}
return {
key: monitor_dict.reference,
......@@ -103,6 +113,7 @@
instance_list = [],
parameter_list = [],
status_url = '',
instance_dict,
i,
instance_content;
......@@ -112,13 +123,15 @@
for (i = 0; i < document_list.length; i += 1) {
// Only one instance per opml-outline
if (document_list[i].data.total_rows === 1) {
instance_list.push(
getInstanceDict(gadget, document_list[i].data.rows[0].value)
instance_dict = getInstanceDict(
gadget,
document_list[i].data.rows[0].value
);
instance_list.push(instance_dict);
if (document_list[i].data.rows[0].value.hasOwnProperty('parameters')) {
parameter_list.push({
title: document_list[i].data.rows[0].value.title,
parameters: document_list[i].data.rows[0].value.parameters,
parameters: instance_dict.parameters,
base_url: document_list[i].data.rows[0].value
._links.private_url.href || '',
index: i
......@@ -172,9 +185,8 @@
function updateParameterBox(parameter_list, title) {
var element = gadget.element.querySelector('table[title="' + title + '"]'),
tmp,
i;
if (!element) {
return;
}
......@@ -182,7 +194,8 @@
if (!parameter_list[i].key) {
continue;
}
element.querySelector('.v-' + parameter_list[i].key).textContent = parameter_list[i].value;
element.querySelector('.v-' + parameter_list[i].key)
.textContent = parameter_list[i].value;
}
}
......@@ -213,34 +226,22 @@
})
.push(function (config_gadget) {
gadget.props.config_gadget = config_gadget;
return gadget.props.config_gadget.render({
url: gadget.state.instance_list[index].private_url +
'/config',
basic_login: gadget.state.opml.basic_login
});
})
.push(function () {
return gadget.props.config_gadget.popupEdit({
url: gadget.state.instance_list._links.private_url.href,
parameters: gadget.state.instance_list[index].parameters,
title: gadget.state.instance_list[index].title,
root_title: gadget.state.instance_list[index]['hosting-title'],
page_options: gadget.props.options,
path: 'config',
key: 'config.tmp'
parameters: gadget.state.instance_list[index].parameters,
document_id: 'config.tmp'
}, function (data) {
var update_promise = [],
i,
monitor_user = '',
monitor_password = '';
// Try to save monitor credential if they are pres
for (i = 0; i < data.length; i += 1) {
if (data[i].key === 'monitor-password') {
monitor_password = data[i].value;
}
if ((data[i].key || data[i].title) === 'monitor-user') {
monitor_user = data[i].value;
}
}
gadget.state.instance_list[index].parameters = data;
updateParameterBox(data, gadget.props.document_list[index].title);
updateParameterBox(data, gadget.state.instance_list[index].title);
$(gadget.element.querySelector('.alert-info'))
.removeClass('ui-content-hidden');
return RSVP.all(update_promise);
});
});
}
......
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21935.10239.63812</string> </value>
<value> <string>961.40930.22839.30634</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1502452997.2</float>
<float>1503585188.82</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -16,6 +16,8 @@
} else {
this.props.jio_storage = jIO.createJIO({
type: "replicatedopml",
remote_storage_unreachable_status: "WARNING",
remote_opml_check_time_interval: 86400000,
local_sub_storage: {
type: "query",
sub_storage: {
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21883.33309.38348</string> </value>
<value> <string>961.37911.38494.42700</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502445069.09</float>
<float>1503418549.74</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -41,7 +41,7 @@
<div style="border: 1px solid rgba(0,0,0,0.1); margin-top: 10px;">
<div class="ui-body">
{{#if message}}
<p><strong>{{status}}</strong>: {{message}}</p>
<p class="ui-text ui-text-pre"><strong>{{status}}</strong>: {{message}}</p>
{{else}}
<p><strong>No output message!</strong></p>
{{/if}}
......
......@@ -243,7 +243,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.20815.19432.23961</string> </value>
<value> <string>961.21883.33309.38348</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -261,7 +261,7 @@
</tuple>
<state>
<tuple>
<float>1502378039.46</float>
<float>1504086738.54</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -243,7 +243,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.17644.54835.1433</string> </value>
<value> <string>961.47920.32703.17493</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -261,7 +261,7 @@
</tuple>
<state>
<tuple>
<float>1502188014.54</float>
<float>1504086069.06</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21935.10239.63812</string> </value>
<value> <string>961.22271.22355.17766</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502465240.41</float>
<float>1504086036.21</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -73,9 +73,9 @@
<input type="password" name="password" required value=""/>
</div>
</div>
<!--<label class="configure-auth">
<input type="checkbox" name="configure-newpwd">Show/hide change password form
</label>-->
<label class="configure-auth">
<input type="checkbox" name="configure-newpwd">Show/hide update password form
</label>
<div class="new-password" style="display: none">
<div class="ui-form">
<div class="ui-field-contain">
......
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502455270.08</float>
<float>1503497281.04</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -30,7 +30,7 @@
+ ":" + addZero(d.getMinutes()) + ":" + addZero(d.getSeconds());
}
function checkCredential(gadget, url, title, hash, opml_hash) {
function checkCredential(gadget, url, title, hash) {
var ouput;
// Verify if login and password are correct for this URL
if (url === undefined) {
......@@ -38,18 +38,6 @@
}
return testUrl(url, hash)
.then(function(result) {
/*if (result.status === 'OK') {
return result;
} else {
result.title = title;
return testUrl(url, opml_hash)
.push(function (sub_result) {
if (sub_result.status !== 'OK') {
return result;
}
return sub_result;
});
}*/
return result;
}, function(error) {
var ko_msg = {
......@@ -57,15 +45,6 @@
msg: error.msg + ' (' + url + ')',
title: title
};
/*if (opml_hash) {
return testUrl(url, opml_hash)
.push(function (result) {
if (result.status === 'OK') {
return {status: 'OK'};
}
return ko_msg;
});
}*/
return ko_msg;
});
}
......@@ -90,20 +69,23 @@
function loadOPMLConfiguration(gadget) {
return gadget.jio_allDocs({
query: 'portal_type:"opml"',
select_list: ['title', 'url', 'active'],
select_list: ['title', 'url', 'active', 'basic_login'],
sort_on: [["title", "ascending"]]
})
.push(function (result) {
var i,
opml_list = [],
cred_list,
content;
for (i = 0; i < result.data.total_rows; i += 1) {
cred_list = atob(result.data.rows[i].value.basic_login).split(":");
opml_list.push({
key: result.data.rows[i].value.title + "#" +
result.data.rows[i].value.url,
href: "#page=settings_configurator&url=" +
result.data.rows[i].value.url +
'&tab=add',
'&tab=add&password=' + cred_list[1] +
'&username=' + cred_list[0],
link: result.data.rows[i].value.url,
title: result.data.rows[i].value.title || '',
status: (result.data.rows[i].value.active) ? "Enabled" : "Disabled"
......@@ -112,7 +94,7 @@
content = opml_url_template({opml_list: opml_list});
gadget.element.querySelector(".opml-tablelinks > tbody")
.innerHTML = content;
return;
return gadget.changeState({"opml_list": opml_list});
});
}
......@@ -146,15 +128,66 @@
if (credential_hash !== undefined) {
xhr.setRequestHeader('Authorization', 'Basic ' + credential_hash);
}
//try {
xhr.send("");
//} catch (e) {
// reject({status: 'ERROR', msg: e});
//}
});
});
}
function changeMonitorPassword(gadget, base_url, title, basic_login,
password) {
var url = base_url,
jio_gadget,
jio_options;
url += (url.endsWith('/') ? '':'/') + 'config/';
gadget.props.gindex += 1;
return gadget.declareGadget("gadget_monitoring_jio.html",
{
element: gadget.element,
scope: 'jio_' + gadget.props.gindex + "_gadget",
sandbox: "public"
}
).push(function(new_gadget) {
jio_gadget = new_gadget;
jio_gadget.createJio({
type: "query",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
type: "dav",
url: url,
basic_login: basic_login
}
}
});
return jio_gadget.get('config');
})
.push(function (doc) {
var i;
if (doc) {
for (i = 0; i < doc.length; i += 1) {
if (doc[i].key === 'monitor-password') {
doc[i].value = password;
return jio_gadget.put('config.tmp', doc);
}
}
}
return new Error("Cannot get document 'config.json' at : " % url);
})
.push(function () {
return {status: 'OK'};
}, function (error) {
console.log(error);
return {
status: 'ERROR',
code: error.target.status,
url: base_url,
title: title
};
});
}
gadget_klass
/////////////////////////////
// state
......@@ -163,12 +196,14 @@
deferred: "",
sync_gadget: "",
selected: "",
jio_gadget: ""
jio_gadget: "",
opml_list: ""
})
/////////////////////////////
// ready
/////////////////////////////
.ready(function (gadget) {
gadget.props = {gindex: 0};
return new RSVP.Queue()
.push(function () {
return gadget.changeState({deferred: RSVP.defer()});
......@@ -203,23 +238,23 @@
panel_action: false*/
})
.push(function () {
return loadOPMLConfiguration(gadget);
})
.push(function () {
var i;
if (options.url !== undefined && options.url !== '') {
gadget.element.querySelector("input[name='url']")
.value = options.url;
if (options.username !== undefined && options.username !== '' &&
options.password !== undefined && options.password !== '') {
//gadget.props.username = options.username;
//gadget.props.password = options.password;
gadget.element.querySelector("input[name='username']")
.value = options.username;
gadget.element.querySelector("input[name='password']")
.value = options.password;
}
}
if (options.username !== undefined && options.username !== '' &&
options.password !== undefined && options.password !== '') {
//gadget.props.username = options.username;
//gadget.props.password = options.password;
gadget.element.querySelector("input[name='username']")
.value = options.username;
gadget.element.querySelector("input[name='password']")
.value = options.password;
}
//return gadget.getSetting('monitor_url_description');
return loadOPMLConfiguration(gadget);
})
.push(function () {
return gadget.getSetting('latest_sync_time');
})
.push(function (latest_sync_time) {
......@@ -303,6 +338,22 @@
return key_list;
}
function setFormValue(data) {
if (data === undefined) {
data = {};
}
gadget.element
.querySelector("input[name='username']").value = data.username || "";
gadget.element
.querySelector("input[name='password']").value = data.password || "";
gadget.element
.querySelector("input[name='new_password']").value = data.new_password || "";
gadget.element
.querySelector("input[name='new_password_confirm']").value = data.new_password_confirm || "";
gadget.element
.querySelector("input[name='url']").value = data.url || "";
}
return new RSVP.Queue()
.push(function () {
return gadget.state.deferred.promise;
......@@ -337,7 +388,7 @@
return gadget.state.sync_gadget.startSync({now: true});
})
.push(function () {
gadget.element.querySelector('.sync-all')
gadget.element.querySelector('.sync-all span')
.textContent = title;
gadget.element.querySelector('.sync-all')
.disabled = false;
......@@ -530,7 +581,7 @@
gadget.element.querySelector('.msgtext-box')
.innerHTML = notify_msg_template({
status: "error",
text: "ERROR while removing OPML(s)"
text: "ERROR while updating OPML(s)"
});
return [];
})
......@@ -594,29 +645,17 @@
button_submit.textContent = submit_text;
}
function clearForm() {
gadget.element
.querySelector("input[name='username']").value = "";
gadget.element
.querySelector("input[name='password']").value = "";
gadget.element
.querySelector("input[name='new_password']").value = "";
gadget.element
.querySelector("input[name='new_password_confirm']").value = "";
gadget.element
.querySelector("input[name='url']").value = "";
}
function pushNewOPML(opml_url, username, password) {
function pushNewOPML(opml_url, username, password, new_password) {
var opml_dict = {
type: "opml",
portal_type: "opml",
url: opml_url,
basic_login: btoa(username + ':' + password),
active: true
};
function validateOPML(basic_login) {
type: "opml",
portal_type: "opml",
url: opml_url,
basic_login: btoa(username + ':' + password),
active: true
},
update_password_list = [];
function validateOPML() {
// read the opml to get the content and title
//delete gadget.state.jio_storage;
button_submit.textContent = "Reading OPML content...";
......@@ -652,13 +691,18 @@
if (opml_result.data.total_rows > 0) {
opml_dict.title = opml_result.data.rows[0].value.title;
for (i = 1; i < opml_result.data.total_rows; i += 1) {
check_list.push(checkCredential(
gadget,
opml_result.data.rows[i].value.url,
opml_result.data.rows[i].value.title,
opml_dict.basic_login,
basic_login
));
if (opml_result.data.rows[i].value.url !== undefined) {
check_list.push(checkCredential(
gadget,
opml_result.data.rows[i].value.url,
opml_result.data.rows[i].value.title,
opml_dict.basic_login
));
update_password_list.push({
base_url: opml_result.data.rows[i].value.url,
title: opml_result.data.rows[i].value.title
});
}
}
button_submit.textContent = "Validating password(s)...";
return RSVP.all(check_list);
......@@ -681,6 +725,50 @@
return false;
}
return status_list[0];
})
.push(function (previous_status) {
var i,
update_promise_list = [];
if (new_password === "") {
return previous_status;
}
if (!previous_status) {
return false;
}
button_submit.textContent = "Changing password(s)...";
for (i = 0; i < update_password_list.length; i += 1) {
update_promise_list.push(changeMonitorPassword(
gadget,
update_password_list[i].base_url,
update_password_list[i].title,
opml_dict.basic_login,
new_password
));
}
return new RSVP.Queue()
.push(function () {
return RSVP.all(update_promise_list);
})
.push(function(result_list) {
var i,
error_msg = "";
for (i = 0; i < result_list.length; i += 1) {
if (result_list[i].status === 'ERROR') {
error_msg += 'ERROR ' + result_list[i].code +
'. [' + result_list[i].title + '] Failed to ' +
'change password, please try again\n';
}
}
if (error_msg !== "") {
alert_box.removeClass('ui-content-hidden')
.text(error_msg);
return false;
} else {
opml_dict.basic_login =
btoa(username + ':' + new_password);
return true;
}
});
});
}
......@@ -693,7 +781,7 @@
})
.push(function (doc) {
current_opml = doc;
return validateOPML(doc.basic_login);
return validateOPML();
})
.push(function (status) {
if (status) {
......@@ -728,7 +816,8 @@
);
return false;
}
return pushNewOPML(opml_url, username, password);
return pushNewOPML(opml_url, username, password,
new_password);
});
}
));
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.22290.30770.8345</string> </value>
<value> <string>961.40699.48372.17271</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502466440.16</float>
<float>1503651680.71</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -19,7 +19,7 @@
.declareMethod('render', function (options) {
var gadget = this,
header = {
"title": 'Monitoring Promise Status'
"title": 'Monitoring Promises Status'
},
listbox_configuration = {
search_page: 'status_list',
......@@ -50,7 +50,7 @@
}],
filter_column: {select: "category", "title": "Status"},
query: {
"limit": [0, 600],
"limit": [0, 400],
select_list: ['source', 'channel_item', 'channel', 'category',
'date', 'comments', 'link', 'lastBuildDate', 'parent_id'],
query: '(portal_type:"promise") AND (active:true)',
......@@ -95,8 +95,8 @@
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("setSetting", "setSetting")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("renderApplication", "renderApplication")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("renderApplication", "renderApplication")
.declareService(function () {
var gadget = this,
current_sync_date;
......
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21935.10239.63812</string> </value>
<value> <string>961.42463.34618.20070</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502455678.21</float>
<float>1503676888.75</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -252,6 +252,7 @@
}
// Default sync interval to 5 minutes
gadget.props.default_sync_interval = 300000;
gadget.props.has_sync_interval = false;
return new RSVP.Queue()
.push(function () {
return gadget.getSetting('sync_data_interval');
......@@ -260,9 +261,9 @@
if (timer_interval === undefined) {
// quickly sync because this is the first run!
gadget.props.timer_interval = 10000;
gadget.props.has_sync_interval = false;
} else {
gadget.props.timer_interval = timer_interval;
gadget.props.has_sync_interval = true;
}
return gadget.getSetting('latest_sync_time');
})
......
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21883.33309.38348</string> </value>
<value> <string>961.40574.58268.18875</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1502445069.16</float>
<float>1503563500.59</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -17,6 +17,7 @@
* {
* "type": "replicatedopml",
* "remote_storage_unreachable_status": "WARNING",
* "remote_opml_check_time_interval": 86400000,
* local_sub_storage: {
* type: "query",
* sub_storage: {
......@@ -28,8 +29,8 @@
*
*/
var rusha = new Rusha();
//SIGNATURE_PREFIX_NAME = "__signature__";
var rusha = new Rusha(),
OPML_ATTACHMENT_NAME = "__opml__";
function generateHash(str) {
return rusha.digestFromString(str);
......@@ -66,6 +67,12 @@
if (this._remote_parser_storage_type === undefined) {
this._remote_parser_storage_type = "parser";
}
this._remote_opml_check_time_interval =
spec.remote_opml_check_time_interval;
if (this._remote_opml_check_time_interval === undefined) {
// one day in miliseconds
this._remote_opml_check_time_interval = 86400000;
}
}
ReplicatedOPMLStorage.prototype.get = function () {
......@@ -216,7 +223,7 @@
JSON.stringify(storage_spec));
}
function getSignatureDocument(context, attachment_id, name) {
function getDocumentAsAttachment(context, attachment_id, name) {
return context._local_sub_storage.getAttachment(attachment_id, name)
.push(undefined, function (error) {
if ((error instanceof jIO.util.jIOError) &&
......@@ -246,8 +253,14 @@
return context._local_sub_storage.get(id);
})
.push(function (doc) {
doc.status = next_status;
return context._local_sub_storage.put(id, doc);
if (doc.portal_type === "promise") {
doc.category = next_status;
return context._local_sub_storage.put(id, doc);
}
if (doc.status !== undefined) {
doc.status = next_status;
return context._local_sub_storage.put(id, doc);
}
});
}
......@@ -255,10 +268,14 @@
if (signature_dict.hasOwnProperty(key)) {
if (signature_dict[key].status !== next_status) {
updateStatus(key);
signature_dict[key].status = next_status;
}
}
}
return update_status_queue;
return update_status_queue
.push(function () {
return signature_dict;
});
}
function loadSubStorage(context, storage_spec, parent_id, type) {
......@@ -288,12 +305,8 @@
if (result === undefined) {
if (context._remote_storage_unreachable_status !== undefined) {
// update status of local documents
// to set unreachable state
return getSignatureDocument(
context,
parent_id,
url
)
// and set unreachable status
return getDocumentAsAttachment(context, parent_id, url)
.push(function (signature_document) {
return updateSubStorageStatus(
context,
......@@ -301,14 +314,14 @@
context._remote_storage_unreachable_status
);
})
.push(function () {
return {};
.push(function (signature_dict) {
return signature_dict;
});
}
return {};
}
result_dict.result = result;
return getSignatureDocument(
return getDocumentAsAttachment(
context,
parent_id,
url
......@@ -324,35 +337,60 @@
var opml_storage,
opml_document_list = [],
delete_key_list = [],
signature_document_list = [],
attachment_document_list = [],
opml_result_list,
current_signature_dict = {},
fetch_remote_opml = false,
id;
id = generateHash(opml_url);
opml_storage = createStorage(context, opml_spec, id);
return opml_storage.allDocs({include_docs: true})
.push(undefined, function (error) {
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404)) {
return {data: {total_rows: 0}};
return getDocumentAsAttachment(context, opml_url, OPML_ATTACHMENT_NAME)
.push(function (opml_doc) {
var current_time = new Date().getTime();
if (opml_doc.expire_time !== undefined) {
fetch_remote_opml = (opml_doc.expire_time - current_time) < 0;
} else {
fetch_remote_opml = true;
}
//throw error;
// throw will cancel all remaning tasks
console.error(error);
return {data: {total_rows: 0}};
})
.push(function (opml_result) {
opml_result_list = opml_result;
if (opml_result.data.total_rows > 0) {
return getSignatureDocument(
context,
id,
opml_url
);
if (fetch_remote_opml) {
return opml_storage.allDocs({include_docs: true})
.push(undefined, function (error) {
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404)) {
return {data: {total_rows: 0}};
}
//throw error;
console.error(error);
return {data: {total_rows: 0}};
})
.push(function (opml_result) {
opml_result_list = opml_result;
if (opml_result.data.total_rows > 0) {
attachment_document_list.push({
id: opml_url,
name: OPML_ATTACHMENT_NAME,
doc: {
expire_time: new Date().getTime() +
context._remote_opml_check_time_interval,
data: opml_result
}
});
return getDocumentAsAttachment(
context,
id,
opml_url
);
}
return {};
})
.push(function (signature_dict) {
current_signature_dict = signature_dict;
});
}
return {};
opml_result_list = opml_doc.data;
})
.push(function (current_signature_dict) {
.push(function () {
var i,
item,
signature,
......@@ -362,7 +400,7 @@
result_list = [],
header_dict = {};
if (opml_result_list.data.total_rows > 0) {
if (opml_result_list.data.total_rows > 0 && fetch_remote_opml) {
header_dict = {
dateCreated: opml_result_list.data.rows[0].doc.dateCreated,
dateModified: opml_result_list.data.rows[0].doc.dateModified,
......@@ -374,12 +412,6 @@
item = opml_result_list.data.rows[i];
if (item.doc.xmlUrl !== undefined) {
id_hash = generateHash(id + item.id);
signature = generateHash(JSON.stringify(item.doc));
// Append this document signature to the list
doc_signature_dict[id_hash] = {
signature: signature
};
result_list.push(loadSubStorage(
context,
{
......@@ -407,37 +439,46 @@
));
}
if (current_signature_dict.hasOwnProperty(id_hash)) {
if (current_signature_dict[id_hash].signature === signature) {
// remote document was not modified, delete and skip add
if (fetch_remote_opml) {
// Append this document signature to the list
signature = generateHash(JSON.stringify(item.doc));
doc_signature_dict[id_hash] = {
signature: signature
};
if (current_signature_dict.hasOwnProperty(id_hash)) {
if (current_signature_dict[id_hash].signature === signature) {
// remote document was not modified, delete and skip add
delete current_signature_dict[id_hash];
skip_add = true;
}
delete current_signature_dict[id_hash];
skip_add = true;
}
delete current_signature_dict[id_hash];
}
Object.assign(item.doc, {
portal_type: "opml-outline",
parent_id: id,
parent_url: opml_url,
reference: id_hash,
active: true
});
Object.assign(item.doc, header_dict);
if (!skip_add) {
opml_document_list.push({
id: id_hash,
doc: item.doc
Object.assign(item.doc, {
portal_type: "opml-outline",
parent_id: id,
parent_url: opml_url,
reference: id_hash,
active: true
});
Object.assign(item.doc, header_dict);
if (!skip_add) {
opml_document_list.push({
id: id_hash,
doc: item.doc
});
}
}
}
}
signature_document_list.push({
id: opml_url,
name: opml_url,
doc: doc_signature_dict
});
delete_key_list.push.apply(delete_key_list,
Object.keys(current_signature_dict));
if (fetch_remote_opml && Object.keys(doc_signature_dict).length > 0) {
attachment_document_list.push({
id: opml_url,
name: opml_url,
doc: doc_signature_dict
});
delete_key_list.push.apply(delete_key_list,
Object.keys(current_signature_dict));
}
return RSVP.all(result_list);
})
.push(function (result_list) {
......@@ -493,47 +534,57 @@
for (i = 0; i < result_list.length; i += 1) {
extra_dict = undefined;
start = 0;
if (result_list[i].type === "promise" &&
result_list[i].result.data.total_rows > 0) {
// the first element of rss is the header
extra_dict = {
lastBuildDate: result_list[i].result.data.rows[0].doc
.lastBuildDate,
channel: result_list[i].result.data.rows[0].doc.description,
channel_item: result_list[i].result.data.rows[0].doc.title
};
applyItemToTree(
result_list[i].result.data.rows[0],
result_list[i],
"rss"
);
start = 1;
}
for (j = start; j < result_list[i].result.data.total_rows; j += 1) {
applyItemToTree(
result_list[i].result.data.rows[j],
result_list[i],
undefined,
extra_dict
if (result_list[i].result.data.total_rows > 0) {
if (result_list[i].type === "promise") {
// the first element of rss is the header
extra_dict = {
lastBuildDate: result_list[i].result.data.rows[0].doc
.lastBuildDate,
channel: result_list[i].result.data.rows[0].doc.description,
channel_item: result_list[i].result.data.rows[0].doc.title
};
applyItemToTree(
result_list[i].result.data.rows[0],
result_list[i],
"rss"
);
start = 1;
}
for (j = start; j < result_list[i].result.data.total_rows; j += 1) {
applyItemToTree(
result_list[i].result.data.rows[j],
result_list[i],
undefined,
extra_dict
);
}
attachment_document_list.push({
id: result_list[i].parent_id,
name: result_list[i].url,
doc: item_signature_dict
});
item_signature_dict = {};
delete_key_list.push.apply(
delete_key_list,
Object.keys(result_list[i].current_signature)
);
} else if (Object.keys(result_list[i].current_signature).length > 0) {
// if the remote data is empty and current_signature is not empty,
// push to storage in case the status was changed
// this help for speed optimisation
attachment_document_list.push({
id: result_list[i].parent_id,
name: result_list[i].url,
doc: result_list[i].current_signature
});
}
signature_document_list.push({
id: result_list[i].parent_id,
name: result_list[i].url,
doc: item_signature_dict
});
item_signature_dict = {};
delete_key_list.push.apply(
delete_key_list,
Object.keys(result_list[i].current_signature)
);
}
return [opml_document_list, delete_key_list, signature_document_list];
return [opml_document_list, delete_key_list, attachment_document_list];
});
}
function pushDocumentToStorage(context, document_list, delete_key_list,
signature_document_list) {
attachment_document_list) {
var document_queue = new RSVP.Queue(),
i;
......@@ -579,7 +630,7 @@
var j,
signature_queue = new RSVP.Queue();
function pushSignature(id, name, element) {
function pushAttachment(id, name, element) {
signature_queue
.push(function () {
return context._local_sub_storage.putAttachment(
......@@ -592,11 +643,11 @@
console.error(error);
});
}
for (j = 0; j < signature_document_list.length; j += 1) {
pushSignature(
signature_document_list[j].id,
signature_document_list[j].name,
signature_document_list[j].doc
for (j = 0; j < attachment_document_list.length; j += 1) {
pushAttachment(
attachment_document_list[j].id,
attachment_document_list[j].name,
attachment_document_list[j].doc
);
}
});
......@@ -667,4 +718,4 @@
jIO.addStorage('replicatedopml', ReplicatedOPMLStorage);
}(jIO, RSVP, Rusha, Blob, console));
\ No newline at end of file
}(jIO, RSVP, Rusha, Blob, console));
......@@ -239,7 +239,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.21883.33309.38348</string> </value>
<value> <string>961.39289.49107.2628</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -257,7 +257,7 @@
</tuple>
<state>
<tuple>
<float>1502445069.19</float>
<float>1503487925.99</float>
<string>UTC</string>
</tuple>
</state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment