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