Commit 9cc69226 authored by Tristan Cavelier's avatar Tristan Cavelier

Revert "XXX WIP renderjs-ify"

This reverts commit f4d8832659acf8927131c43bc267401b587fa43f.
parent cfcb4586
body { width: 80vw; margin: auto; padding-top: 1%; }
/* h1 { align-text: center; margin: auto; } */
/*td { padding: 0 2%; }/**/
td { padding: 0 1em; }/**/
table { border: 1px solid black; }
table > table { margin-top: 1em; }
input {
box-sizing: border-box;
min-height: 10mm;
min-width: 10mm;
}
button {
box-sizing: border-box;
min-height: 10mm;
min-width: 10mm;
background-color: lightgray;
background: linear-gradient(180deg, #F6F6F6 0%, #DDDDDD 100%);
border-radius: 2px;
border-style: solid;
border-width: 1px;
border-color: #A4A4A4;
}
a.as-button {
display: inline-block;
box-sizing: border-box;
min-height: 10mm;
min-width: 10mm;
padding: 0.5em 0.5em;
text-align: center;
text-decoration: initial;
}
a.as-button {
color: black;
background-color: lightgray;
background: linear-gradient(180deg, #F6F6F6 0%, #DDDDDD 100%);
border-radius: 2px;
border-style: solid;
border-width: 1px;
border-color: #A4A4A4;
}
a.as-button:active, button:active {
background-color: white;
background: linear-gradient(0deg, #F6F6F6 0%, #DDDDDD 100%);
}
a.as-button:hover, button:hover {
border-color: #777777;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Documents</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../lib/jquery-mobile-1.4.5.min.css" />
<script src="../lib/jquery-1.11.3.min.js"></script>
<script src="../lib/rsvp-2.0.4.min.js"></script>
<script src="../lib/renderjs-latest-wip-romain.js"></script>
<script src="../lib/jquery-mobile-1.4.5.min.js"></script>
<!--script src="../lib/jio-v3.2.1.min.js"></script-->
<script src="../lib/i18next-1.10.1.min.js"></script>
</head>
<body>
<h1>KVM Monitoring interface</h1>
<h2>System health status</h2>
<p>This interface allow to see the status of several features, it may show problems and sometimes provides a way to fix them.</p>
<p>Red square means the feature has a problem, green square means it is ok.</p>
<!--div data-role="page" id="documents">
<div data-role="header">
<h1 class="translate" data-i18n="all.documents"></h1>
<a href="#document%3Fid=new" class="ui-btn ui-btn-right ui-shadow ui-icon-star ui-btn-icon-left ui-corner-all" data-i18n="all.new"></a>
</div>
<div class="ui-content">
<div class="center">
<div data-role="controlgroup" data-type="horizontal">
<a href="#documents%3Fsort=title" class="ui-btn ui-shadow" data-i18n="all.title"></a>
<a href="#documents%3Fsort=start_date" class="ui-btn ui-shadow" data-i18n="all.begin"></a>
<a href="#documents%3Fsort=end_date" class="ui-btn ui-shadow" data-i18n="all.end"></a>
<a href="#documents%3Fsort=status" class="ui-btn ui-shadow" data-i18n="all.status"></a>
<a href="#documents%3Fsort=description" class="ui-btn ui-shadow" data-i18n="all.text"></a>
</div>
</div>
<form method="POST" action="#" class="search_tasks">
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear">
<input type="text" name="search_input" value="" data-enhanced="true" class="" data-i18n="[placeholder]all.search_documents" />
<div class="ui-btn ui-input-clear ui-input-btn ui-corner-all ui-icon-search ui-btn-icon-notext">
<span class="ui-hidden-accessible" data-i18n="all.search">Submit</span>
<input type="submit" data-i18n="[value]all.search" value="Submit" data-enhanced="true" />
</div>
</div>
</form>
<ul data-role="listview" data-inset="true"></ul>
</div>
</div-->
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Footer</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../lib/jquery-mobile-1.4.5.min.css" />
<script src="../lib/jquery-1.11.3.min.js"></script>
<script src="../lib/rsvp-2.0.4.min.js"></script>
<script src="../lib/renderjs-latest-wip-romain.js"></script>
<script src="../lib/jquery-mobile-1.4.5.min.js"></script>
<!--script src="../lib/jio-v3.2.1.min.js"></script-->
<script src="../lib/i18next-1.10.1.min.js"></script>
</head>
<body>
<div data-role="footer" data-position="fixed" data-theme="a">
<div data-role="navbar">
<ul>
<li><a href="#home" data-icon="bullets" class="translate" data-i18n="all.home">A</a></li>
<li><a href="#documents" data-icon="bullets" class="translate" data-i18n="all.documents">B</a></li>
<!--li><a href="#projects" data-icon="bars" class="translate" data-i18n="all.projects"></a></li>
<li><a href="#settings" data-icon="gear" class="translate" data-i18n="all.settings"></a></li-->
</ul>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>KVM monitoring interface (navigation)</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--link rel="stylesheet" href="../lib/jquery-mobile-1.4.5.min.css" /-->
<script src="../lib/jquery-1.11.3.min.js"></script>
<!--script src="../lib/jquery-mobile-1.4.5.min.js"></script-->
<script src="../lib/rsvp-2.0.4.min.js"></script>
<script src="../lib/renderjs-0.7.5.min.js"></script>
<!-- script src="../lib/i18next-1.10.1.min.js"></script -->
<script src="../js/navigation.js"></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>KVM monitoring interface</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../lib/jquery-mobile-1.4.5.min.css" />
<script src="../lib/jquery-1.11.3.min.js"></script>
<script src="../lib/jquery-mobile-1.4.5.min.js"></script>
<script src="../lib/rsvp-2.0.4.min.js"></script>
<script src="../lib/renderjs-latest-wip-romain.js"></script>
<script src="../lib/jio-v3.2.1.min.js"></script>
<!--script src="../lib/i18next-1.10.1.min.js"></script-->
<script src="../js/web-storage.js"></script>
<script src="../js/storage.js"></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>KVM monitoring interface</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--link rel="stylesheet" href="../lib/jquery-mobile-1.4.5.min.css" /-->
<script src="../lib/jquery-1.11.3.min.js"></script>
<!--script src="../lib/jquery-mobile-1.4.5.min.js"></script-->
<script src="../lib/rsvp-2.0.4.min.js"></script>
<script src="../lib/renderjs-latest-wip-romain.js"></script>
<script src="../lib/i18next-1.10.1.min.js"></script>
<script src="../js/translation.js"></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <link rel="stylesheet" href="monitor.css" />
<title>KVM monitoring interface</title> <script src="monitor.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="lib/jquery-mobile-1.4.5.min.css" />
<script src="lib/jquery-1.11.3.min.js"></script>
<script src="lib/jquery-mobile-1.4.5.min.js"></script>
<script src="lib/rsvp-2.0.4.min.js"></script>
<script src="lib/renderjs-latest-wip-romain.js"></script>
<script src="lib/i18next-1.10.1.min.js"></script>
<script src="js/monitor.js"></script>
</head> </head>
<body> <body>
<div data-gadget-url="gadget/translation.html" data-gadget-scope="translation"></div> <noscript>Please enable javascript on your browser to make this application to work.</noscript>
<div data-gadget-url="gadget/storage.html" data-gadget-scope="storage"></div>
<div data-gadget-url="gadget/document.html" data-gadget-scope="document"></div>
<div data-gadget-url="gadget/footer.html" data-gadget-scope="footer"></div>
</body> </body>
</html> </html>
/*jslint indent: 2, nomen: true */
/*global console, window, document, rJS, RSVP, $ */
(function (window, document, rJS, $) {
"use strict";
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
function translateAll(gadget) {
return gadget.getDeclaredGadget("translation").push(function (translation) {
return translation.translateAll();
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
return translateAll(g);
})
.push(function () {
$(g.props.element).trigger("create");
//g.props.loading_counter = 0;
//g.props.content_element = element.querySelector('.gadget-content');
});
})
/////////////////
// Translation //
/////////////////
.allowPublicAcquisition("translation_translateAll", function () { // argument_list
return translateAll(this);
})
.allowPublicAcquisition("translation_changeLanguage", function (param_list) {
return this.getDeclaredGadget("translation")
.push(function (translation) {
return translation.changeLanguage.apply(translation, param_list);
});
})
.allowPublicAcquisition("translation_t", function (param_list) {
return this.getDeclaredGadget("translation")
.push(function (translation) {
return translation.t.apply(translation, param_list);
});
})
return;
// block JQM auto-start
$(document)
.on("mobileinit", function () {
$.mobile.autoInitializePage = false;
});
function logError(first) {
if (arguments.length === 1) {
if (first instanceof Error) {
return console.error(first.name + ": " + first.message + "\n" + first.stack);
}
}
return console.error.apply(console, arguments);
}
rJS(window)
// /**
// * ready handler executing when the gadget is ready
// * @method ready
// * @param {Object} g Gadget object
// */
// .ready(function (g) {
// g.render();
// })
/* ==================================================================== */
/* ENTRY POINT */
/* ==================================================================== */
/**
* main gadget initializer which loads all gadgets and calls render
* method of each gadget if it's available
* @method render
*/
.declareMethod('render2', function () {
var gadget_list, gadget = this;
// load init gadgets
return RSVP.all([
// translation methods
gadget.declareGadget(TRANSLATION_GADGET, {
element: gadget.__element,
scope: "translate"
}),
// // utility methods
// gadget.declareGadget(UTILITIES_GADGET, {
// element: gadget.__element,
// scope: "util"
// }),
// storage methods
gadget.declareGadget(STORAGE_GADGET, {
element: gadget.__element,
scope: "storage"
}),
// page navigation
gadget.declareGadget(NAVIGATION_GADGET, {
element: gadget.__element
})
])
.then(function (init_gadgets) {
gadget_list = init_gadgets;
// // load gadgets which depend on the previous gadgets
// // (for example, a global panel needs to be in the first set
// // as it must be the first element in the body)
return RSVP.all([
// global footer gadget
gadget.declareGadget(FOOTER_GADGET, {
element: gadget.__element,
scope: "footer"
}),
// index page (empty)
gadget.declareGadget(DOCUMENT_GADGET, {
element: gadget.__element
})
]);
})
.then(function (index_gadgets) {
var i, len, response_gadget;
console.log(index_gadgets);
console.log(index_gadgets[1].__element.querySelector("div"));
// merge both initialization gadget responses
gadget_list = gadget_list.concat(index_gadgets);
// initialize gadgets that expose render() method
for (i = 0, len = gadget_list.length; i < len; i += 1) {
response_gadget = gadget_list[i];
if (response_gadget.render) {
response_gadget.render();
}
}
})
.then(function () {
var i, len, el, kids;
// now start JQM and enhance elements manually
$.mobile.initializePage();
kids = document.body.children;
for (i = 0, len = kids.length; i < len; i += 1) {
el = kids[i];
switch (el.getAttribute("data-role")) {
case "footer":
$(el).toolbar().enhanceWithin();
break;
}
}
})
.fail(logError);
})
/* ======================== METHODS EXPOSED =========================== */
/////////////////
// Translation //
/////////////////
.allowPublicAcquisition("translate_translateAll", function (param_list) {
return this.getDeclaredGadget("translate")
.then(function (translate) {
return translate.translateAll.apply(translate, param_list);
});
})
.allowPublicAcquisition("translate_changeLanguage", function (param_list) {
return this.getDeclaredGadget("translate")
.then(function (translate) {
return translate.changeLanguage.apply(translate, param_list);
});
})
.allowPublicAcquisition("translate_t", function (param_list) {
return this.getDeclaredGadget("translate")
.then(function (translate) {
return translate.t.apply(translate, param_list);
});
})
/////////////
// Storage //
/////////////
.allowPublicAcquisition("storage_getAtachment", function (param_list) {
return this.getDeclaredGadget("storage")
.then(function (storage) {
return storage.getAttachment.apply(storage, param_list);
});
});
/* ========================= METHODS NEEDED =========================== */
/* ==================================================================== */
/* METHOD INDEX */
/* ==================================================================== */
}(window, document, rJS, $));
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global console, window, document, rJS, RSVP, $ */
(function (window, document, rJS) {
"use strict";
function logError(first) {
if (arguments.length === 1) {
if (first instanceof Error) {
return console.error(first.name + ": " + first.message + "\n" + first.stack);
}
}
return console.error.apply(console, arguments);
}
rJS(window)
/**
* Override navigation of jQuery Mobile and allow deeplinking. Missing
* pages will now be loaded and added to the DOM as new gadgets - and
* removed again once the user leaves them.
* @method render
* @param {Object} gadget Gadget object
*/
.declareMethod('render', function () {
var gadget = this;
// helper: render new gadget
function renderNewGadget(my_gadget, my_page_name) {
if (my_gadget.render) {
my_gadget.render();
}
$.mobile.changePage("#" + my_page_name);
document.getElementById(my_page_name)
.setAttribute("data-external-page", true);
}
// helper: create new gadget and integrate it in application
function createNewGadget(my_target_name) {
return gadget.declareGadget(
"./" + my_target_name + ".html",
{"element": gadget.__element, "scope": my_target_name}
)
.then(function (new_gadget) {
return renderNewGadget(new_gadget, my_target_name);
})
.fail(logError);
}
// helper: override default JQM navigation, allow deeplinks and
// handle new pages being added to the document
function navigationHandler(e, data) {
var target, clean_url, parsed_url;
if (e && data) {
if (typeof data.toPage === "string") {
target = data.toPage.split("#")[1];
// overwrite JQM history
} else if ($.mobile.navigate.history.initialDst &&
window.location.hash !== "") {
// this is the inital page (not) loaded
// this page needs to be stored as initial page in JQM
clean_url = window.location.href.split("#")[0];
parsed_url = $.mobile.path.parseUrl(clean_url);
target = $.mobile.navigate.history.initialDst;
// remove initialDist, otherwise closing popups
// will trigger double backward transition.
delete $.mobile.navigate.history.initialDst;
// Correctly set index as first page in JQM history
$.mobile.navigate.history.stack[0].hash = "";
$.mobile.navigate.history.stack[0].url = clean_url;
$.mobile.path.documentUrl = parsed_url;
$.mobile.path.documentBase = parsed_url;
}
}
// load "missing pages" into DOM and re-trigger transition
if (target && !document.getElementById(target)) {
e.preventDefault();
return createNewGadget(target)
.fail(logError);
}
}
// helper: remove page and gadget when user leaves
// TODO: is_enhanced check should not be necessary, same as submit...
function cleanupHandler(e) {
var page, id, is_enhanced;
page = e.target;
id = page.id;
is_enhanced = $(page).data("mobilePage") || $(page).page("instance");
if (page.getAttribute('data-external-page')) {
if (is_enhanced) {
$(this).page('destroy').remove();
}
return gadget.dropGadget(id)
.fail(logError);
}
}
// START:
$(document)
.on('pagebeforechange', navigationHandler)
.on('pagehide', 'div.ui-page', cleanupHandler);
});
/* ======================== METHODS TO EXPOSE ========================= */
/* ========================= METHODS NEEDED =========================== */
}(window, document, rJS));
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global console, window, rJS, jIO, RSVP */
(function (window, rJS) {
"use strict";
/**
* renderJS gadget chained statement
*/
rJS(window)
/**
* ready handler executing when the gadget is ready
* @method ready
* @param {Object} gadget Gadget object
*/
.ready(function (gadget) {
gadget.state_parameter_dict = {};
// // initial storage configuration parameters
// gadget.state_parameter_dict.config = {
// "items": {
// "type": "local",
// "username": "taskman",
// "application_name": "items"
// },
// "admin": {
// "type": "local",
// "username": "taskman",
// "application_name": "admin"
// }
// };
// // storage categories
// gadget.state_parameter_dict.storage_category_list = [
// {"value": "local"},
// {"value": "webdav"},
// {"value": "indexeddb"},
// {"value": "replicate"}
// ];
// // create items storage
// gadget.state_parameter_dict.items_storage =
// jIO.createJIO(gadget.state_parameter_dict.config.items);
// // create admin storage to allow switching between storages
// gadget.state_parameter_dict.admin_storage =
// jIO.createJIO(gadget.state_parameter_dict.config.admin);
// // flag active
// gadget.state_parameter_dict.config.items.active = true;
gadget.state_parameter_dict.config = {"type": "web"};
gadget.state_parameter_dict.items_storage = jIO.createJIO(gadget.state_parameter_dict.config);
})
/**
* handler for render gadget
* @method render
*/
.declareMethod('render', function () {
// var definition, config, queue, gadget, storage, config_dict, i, len,
// dict, category, category_list;
// gadget = this;
// dict = gadget.state_parameter_dict;
// queue = new RSVP.Queue();
// config_dict = dict.config;
// storage = dict.admin_storage;
// category_list = dict.storage_category_list;
// // add storage definitions to admin storage
// for (definition in config_dict) {
// if (config_dict.hasOwnProperty(definition)) {
// config = config_dict[definition];
// config.portal_type = "storage_definition";
// config._id = config.application_name;
// queue.push(storage.put(config));
// }
// }
// // add storage types
// for (i = 0, len = category_list.length; i < len; i += 1) {
// category = category_list[i];
// category.portal_type = "portal_category";
// category.category_type = "storage_type";
// category._id = category.value;
// queue.push(storage.put(category));
// }
// return queue;
return;
})
/**
* connector to jIO getAttachment method
* @method getAttachment
* @returns {Promise} getAttachment response
*/
.declareMethod('getAttachment', function () {
var storage = this.state_parameter_dict.items_storage;
return storage.getAttachment.apply(storage, arguments);
});
}(window, rJS));
/*jslint indent: 2, nomen: true */
/*global console, window, document, rJS, RSVP, $ */
(function (window, rJS) {
"use strict";
rJS(window)
/**
* gadget initializer called through ready
* @method render
* @param {Object} gadget Gadget object
*/
.declareMethod('render', function () {
var gadget = this;
$.i18n.init({
"use_browser_language": true,
"lng": "en-EN",
"load": "current",
"fallbackLng": false,
"resGetPath": "lang/__lng__/__ns__.json",
"ns": "dict",
"getAsync": false
}, gadget.translateAll);
})
/* ======================== METHODS TO EXPOSE ========================= */
/**
* translate all elements in the DOM
* @method translateAll
* @param {Array} list Array of elements to translate
*/
.declareMethod('translateAll', function (list) {
/*global i18n */
var i, l, element, lookup, targets, target, route_text, base, len,
has_breaks, elements;
if (!list || typeof list === "function" || typeof list === "object") {
base = document;
} else {
base = list[0][0];
}
elements = base.querySelectorAll("[data-i18n]");
for (i = 0, len = elements.length; i < len; i += 1) {
element = elements[i];
lookup = element.getAttribute("data-i18n");
// JQM inputs > this avoids having to call checkboxRadio("refresh")!
if (element.tagName === "INPUT") {
switch (element.type) {
case "submit":
case "reset":
case "button":
route_text = true;
break;
}
}
if (lookup) {
if (lookup.indexOf(";") > -1) {
targets = lookup.split(";");
} else {
targets = [lookup];
}
for (l = 0; l < targets.length; l += 1) {
target = targets[l].split("]");
switch (target[0]) {
case "[placeholder":
case "[alt":
case "[title":
element.setAttribute(target[0].substr(1), i18n.t(target[1]));
break;
case "[value":
has_breaks = element.previousSibling.textContent.match(/\n/g);
if (route_text && (has_breaks || []).length === 0) {
element.previousSibling.textContent = i18n.t(target[1]);
}
element.value = i18n.t(target[1]);
break;
case "[parent":
element.parentNode.childNodes[0].textContent = i18n.t(target[1]);
break;
case "[node":
element.childNodes[0].textContent = i18n.t(target[1]);
break;
case "[html":
element.innerHTML = i18n.t(target[1]);
break;
default:
// NOTE: be careful of emptying elements with children!
while (element.hasChildNodes()) {
element.removeChild(element.lastChild);
}
element.appendChild(document.createTextNode(i18n.t(target[0])));
break;
}
}
}
// handle <select> span...
//if (element.tagName === "OPTION") {
// if (element.selected && element.parentNode.previousSibling) {
// element.parentNode.previousSibling.textContent =
// element.textContent;
// }
//}
}
})
/**
* lookup a translation pointer in the current language
* @method t
* @param {String} text Dictionary pointer
*/
.declareMethod('t', function (text) {
return $.i18n.t(text);
})
/**
* Change language triggered through form submit
* @method changeLanguage
* @param {Object} obj Submitted form including new language
*/
.declareMethod('changeLanguage', function (obj) {
$.i18n.setLng(obj.change_language, this.translateAll());
});
/* ========================= METHODS NEEDED =========================== */
}(window, rJS));
/*!
* Copyright 2015, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint indent: 2 */
/*global XMLHttpRequest, jIO, RSVP */
(function (XMLHttpRequest, jIO, RSVP) {
"use strict";
function WebStorage() {
return;
}
WebStorage.prototype.getAttachment = function (id, name) {
/*jslint unparam: true */
var deferred = RSVP.defer(), xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.onload = function (event) {
var target = event.target;
if (target.status < 400) {
deferred.resolve(target.response);
} else {
deferred.reject(jIO.util.jIOError(target.statusText, target.status));
}
};
xhr.onerror = function () {
deferred.reject(jIO.util.jIOError("Unknown", 0));
};
xhr.onabort = function () {
deferred.reject(jIO.util.jIOError("Aborted", 0));
};
xhr.open("GET", name, true);
xhr.send();
deferred.promise.cancel = xhr.abort.bind(xhr);
return deferred.promise;
};
jIO.addStorage("web", WebStorage);
}(XMLHttpRequest, jIO, RSVP));
{
"all": {
"home": "Home",
"sort": "Sort",
"title": "Title",
"begin_date": "Begin Date",
"end_date": "End Date",
"begin": "Start",
"end": "Ende",
"text": "Text",
"status": "Status",
"description": "Description",
"documents": "Documents",
"new": "New",
"search": "Search",
"search_documents": "Search Documents...",
"projects": "Projects",
"settings": "Settings"
}
}
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
!function(){var a,b;!function(){var c={},d={};a=function(a,b,d){c[a]={deps:b,callback:d}},b=function(a){if(d[a])return d[a];d[a]={};var e=c[a];if(!e)throw new Error("Module '"+a+"' not found.");for(var f,g=e.deps,h=e.callback,i=[],j=0,k=g.length;k>j;j++)"exports"===g[j]?i.push(f={}):i.push(b(g[j]));var l=h.apply(this,i);return d[a]=f||l}}(),a("rsvp/all",["rsvp/promise","exports"],function(a,b){"use strict";function c(a,b){function c(){for(var a,c=0;c<b.length;c++)a=b[c],a&&"function"==typeof a.then&&"function"==typeof a.cancel&&a.cancel()}if("[object Array]"!==Object.prototype.toString.call(b))throw new TypeError("You must pass an array to all.");return new f(function(d,e,f){function g(a){return function(b){h(a,b)}}function h(a,b){l[a]=b,--m===n&&(0===n?d(l):(d(b),c()))}function i(a){return function(b){f({index:a,value:b})}}function j(a){e(a),c()}var k,l=[],m=b.length,n=b.length-a;0===m&&(1===a?d():d([]));for(var o=0;o<b.length;o++)k=b[o],k&&"function"==typeof k.then?k.then(g(o),j,i(o)):h(o,k)},c)}function d(a){return c(a.length,a)}function e(a){return c(1,a)}var f=a.Promise;b.all=d,b.any=e}),a("rsvp/async",["exports"],function(a){"use strict";function b(){return function(a,b){process.nextTick(function(){a(b)})}}function c(){return function(a,b){setImmediate(function(){a(b)})}}function d(){var a=[],b=new h(function(){var b=a.slice();a=[],b.forEach(function(a){var b=a[0],c=a[1];b(c)})}),c=document.createElement("div");return b.observe(c,{attributes:!0}),window.addEventListener("unload",function(){b.disconnect(),b=null},!1),function(b,d){a.push([b,d]),c.setAttribute("drainQueue","drainQueue")}}function e(){return function(a,b){i.setTimeout(function(){a(b)},1)}}var f,g="undefined"!=typeof window?window:{},h=g.MutationObserver||g.WebKitMutationObserver,i="undefined"!=typeof global?global:this;f="function"==typeof setImmediate?c():"undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():h?d():e(),a.async=f}),a("rsvp/cancellation_error",["exports"],function(a){"use strict";function b(a){if(this.name="cancel",void 0!==a&&"string"!=typeof a)throw new TypeError("You must pass a string.");this.message=a||"Default Message"}b.prototype=new Error,b.prototype.constructor=b,a.CancellationError=b}),a("rsvp/config",["rsvp/async","exports"],function(a,b){"use strict";var c=a.async,d={};d.async=c,b.config=d}),a("rsvp/defer",["rsvp/promise","exports"],function(a,b){"use strict";function c(){var a={resolve:void 0,reject:void 0,promise:void 0};return a.promise=new d(function(b,c){a.resolve=b,a.reject=c}),a}var d=a.Promise;b.defer=c}),a("rsvp/events",["exports"],function(a){"use strict";var b=function(a,b){this.type=a;for(var c in b)b.hasOwnProperty(c)&&(this[c]=b[c])},c=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c][0]===b)return c;return-1},d=function(a){var b=a._promiseCallbacks;return b||(b=a._promiseCallbacks={}),b},e={mixin:function(a){return a.on=this.on,a.off=this.off,a.trigger=this.trigger,a},on:function(a,b,e){var f,g,h=d(this);for(a=a.split(/\s+/),e=e||this;g=a.shift();)f=h[g],f||(f=h[g]=[]),-1===c(f,b)&&f.push([b,e])},off:function(a,b){var e,f,g,h=d(this);for(a=a.split(/\s+/);f=a.shift();)b?(e=h[f],g=c(e,b),-1!==g&&e.splice(g,1)):h[f]=[]},trigger:function(a,c){var e,f,g,h,i,j=d(this);if(e=j[a])for(var k=0;k<e.length;k++)f=e[k],g=f[0],h=f[1],"object"!=typeof c&&(c={detail:c}),i=new b(a,c),g.call(h,i)}};a.EventTarget=e}),a("rsvp/hash",["rsvp/defer","exports"],function(a,b){"use strict";function c(a){var b=0;for(var c in a)b++;return b}function d(a){var b={},d=e(),f=c(a);0===f&&d.resolve({});var g=function(a){return function(b){h(a,b)}},h=function(a,c){b[a]=c,0===--f&&d.resolve(b)},i=function(a){d.reject(a)};for(var j in a)a[j]&&"function"==typeof a[j].then?a[j].then(g(j),i):h(j,a[j]);return d.promise}var e=a.defer;b.hash=d}),a("rsvp/node",["rsvp/promise","rsvp/all","exports"],function(a,b,c){"use strict";function d(a,b){return function(c,d){c?b(c):arguments.length>2?a(Array.prototype.slice.call(arguments,1)):a(d)}}function e(a){return function(){var b,c,e=Array.prototype.slice.call(arguments),h=this,i=new f(function(a,d){b=a,c=d});return g(e).then(function(e){e.push(d(b,c));try{a.apply(h,e)}catch(f){c(f)}}),i}}var f=a.Promise,g=b.all;c.denodeify=e}),a("rsvp/promise",["rsvp/config","rsvp/events","rsvp/cancellation_error","exports"],function(a,b,c,d){"use strict";function e(a){return f(a)||"object"==typeof a&&null!==a}function f(a){return"function"==typeof a}function g(a){m.onerror&&m.onerror(a.detail)}function h(a,b){a===b?j(a,b):i(a,b)||j(a,b)}function i(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(e(b)&&(d=b.then,f(d)))return a.on("promise:cancelled",function(){f(b.cancel)&&b.cancel()}),d.call(b,function(d){return c?!0:(c=!0,b!==d?h(a,d):j(a,d),void 0)},function(b){return c?!0:(c=!0,k(a,b),void 0)}),!0}catch(g){return k(a,g),!0}return!1}function j(a,b){m.async(function(){a.isFulfilled||a.isRejected||(a.trigger("promise:resolved",{detail:b}),a.isFulfilled=!0,a.fulfillmentValue=b)})}function k(a,b){m.async(function(){a.isFulfilled||a.isRejected||(a.trigger("promise:failed",{detail:b}),a.isRejected=!0,a.rejectedReason=b)})}function l(a,b){m.async(function(){a.trigger("promise:notified",{detail:b})})}var m=a.config,n=b.EventTarget,o=c.CancellationError,p=function(a,b){var c=this,d=!1;if("function"!=typeof a)throw new TypeError("You must pass a resolver function as the sole argument to the promise constructor");if(void 0!==b&&"function"!=typeof b)throw new TypeError("You can only pass a canceller function as the second argument to the promise constructor");if(!(c instanceof p))return new p(a,b);var e=function(a){d||(d=!0,h(c,a))},f=function(a){d||(d=!0,k(c,a))},i=function(a){d||l(c,a)};this.on("promise:failed",function(a){this.trigger("error",{detail:a.detail})},this),this.on("error",g),this.cancel=function(){if(!d){if(void 0!==b)try{b()}catch(a){return f(a),void 0}f(new o)}};try{a(e,f,i)}catch(j){f(j)}},q=function(a,b,c,d){var e,g,j,l,m=f(c);if(!b.isFulfilled&&!b.isRejected){if(m)try{e=c(d.detail),j=!0}catch(n){l=!0,g=n}else e=d.detail,j=!0;i(b,e)||(m&&j?h(b,e):l?k(b,g):"resolve"===a?h(b,e):"reject"===a&&k(b,e))}},r=function(a,b,c){var d;if("function"==typeof b){try{d=b(c.detail)}catch(e){return}l(a,d)}else l(a,c.detail)};p.prototype={constructor:p,isRejected:void 0,isFulfilled:void 0,rejectedReason:void 0,fulfillmentValue:void 0,then:function(a,b,c){this.off("error",g);var d=new this.constructor(function(){},function(){d.trigger("promise:cancelled",{})});return this.isFulfilled&&m.async(function(b){q("resolve",d,a,{detail:b.fulfillmentValue})},this),this.isRejected&&m.async(function(a){q("reject",d,b,{detail:a.rejectedReason})},this),this.on("promise:resolved",function(b){q("resolve",d,a,b)}),this.on("promise:failed",function(a){q("reject",d,b,a)}),this.on("promise:notified",function(a){r(d,c,a)}),d},fail:function(a){return this.then(null,a)},always:function(a){return this.then(a,a)}},n.mixin(p.prototype),d.Promise=p}),a("rsvp/queue",["rsvp/promise","rsvp/timeout","exports"],function(a,b,c){"use strict";function d(a){if(this.name="resolved",void 0!==a&&"string"!=typeof a)throw new TypeError("You must pass a string.");this.message=a||"Default Message"}var e=a.Promise,f=b.delay;d.prototype=new Error,d.prototype.constructor=d;var g=function(){function a(){for(var a=0;2>a;a++)k[a].cancel()}var b,c,h,i,j=this,k=[];return this instanceof g?(b=new e(function(a,b){c=function(b){return i?void 0:(j.isFulfilled=!0,j.fulfillmentValue=b,i=!0,a(b))},h=function(a){return i?void 0:(j.isRejected=!0,j.rejectedReason=a,i=!0,b(a))}},a),k.push(f()),k.push(k[0].then(function(){k.splice(0,2),0===k.length&&c()})),j.cancel=function(){i||(i=!0,b.cancel(),b.fail(function(a){j.isRejected=!0,j.rejectedReason=a}))},j.then=function(){return b.then.apply(b,arguments)},j.push=function(a,b){var e,f=k[k.length-1];if(i)throw new d;return e=f.then(a,b),k.push(e),k.push(e.then(function(a){return k.splice(0,2),0!==k.length?a:(c(a),void 0)},function(a){if(k.splice(0,2),0!==k.length)throw a;h(a)})),this},void 0):new g};g.prototype=Object.create(e.prototype),g.prototype.constructor=g,c.Queue=g,c.ResolvedQueueError=d}),a("rsvp/reject",["rsvp/promise","exports"],function(a,b){"use strict";function c(a){return new d(function(b,c){c(a)})}var d=a.Promise;b.reject=c}),a("rsvp/resolve",["rsvp/promise","exports"],function(a,b){"use strict";function c(a){return new d(function(b,c){if("object"==typeof a&&null!==a){var d=a.then;if(void 0!==d&&"function"==typeof d)return d.apply(a,[b,c])}return b(a)},function(){void 0!==a&&void 0!==a.cancel&&a.cancel()})}var d=a.Promise;b.resolve=c}),a("rsvp/rethrow",["exports"],function(a){"use strict";function b(a){throw c.setTimeout(function(){throw a}),a}var c="undefined"==typeof global?this:global;a.rethrow=b}),a("rsvp/timeout",["rsvp/promise","exports"],function(a,b){"use strict";function c(a,b,c){function d(d,e){g=setTimeout(function(){b?e(c):d(c)},a)}function e(){clearTimeout(g)}var g;return new f(d,e)}function d(a,b){return c(a,!1,b)}function e(a){return c(a,!0,"Timed out after "+a+" ms")}var f=a.Promise;f.prototype.delay=function(a){return this.then(function(b){return d(a,b)})},b.delay=d,b.timeout=e}),a("rsvp",["rsvp/events","rsvp/cancellation_error","rsvp/promise","rsvp/node","rsvp/all","rsvp/queue","rsvp/timeout","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){"use strict";function o(a,b){C[a]=b}var p=a.EventTarget,q=b.CancellationError,r=c.Promise,s=d.denodeify,t=e.all,u=e.any,v=f.Queue,w=f.ResolvedQueueError,x=g.delay,y=g.timeout,z=h.hash,A=i.rethrow,B=j.defer,C=k.config,D=l.resolve,E=m.reject;n.CancellationError=q,n.Promise=r,n.EventTarget=p,n.all=t,n.any=u,n.Queue=v,n.ResolvedQueueError=w,n.delay=x,n.timeout=y,n.hash=z,n.rethrow=A,n.defer=B,n.denodeify=s,n.configure=o,n.resolve=D,n.reject=E}),window.RSVP=b("rsvp")}(window);
\ No newline at end of file
...@@ -22,6 +22,8 @@ def main(): ...@@ -22,6 +22,8 @@ def main():
for filename in os.listdir(configuration_folder_location) for filename in os.listdir(configuration_folder_location)
if os.path.isfile(os.path.join(configuration_folder_location, filename)) if os.path.isfile(os.path.join(configuration_folder_location, filename))
] ]
# search for promises in ...?
# XXX see old monitor.py.in
# generate monitor.json # generate monitor.json
monitor_dict = {} monitor_dict = {}
tmp = softConfigGet(config, "monitor", "title") tmp = softConfigGet(config, "monitor", "title")
...@@ -50,7 +52,8 @@ def main(): ...@@ -50,7 +52,8 @@ def main():
for service_config in service_config_list: for service_config in service_config_list:
createSymlinksFromConfig((config, "monitor", "public-folder"), (service_config, "service", "public-path-list")) createSymlinksFromConfig((config, "monitor", "public-folder"), (service_config, "service", "public-path-list"))
createSymlinksFromConfig((config, "monitor", "private-folder"), (service_config, "service", "private-path-list")) createSymlinksFromConfig((config, "monitor", "private-folder"), (service_config, "service", "private-path-list"))
# let crontab execute the promises via the promise executor # run scripts according to frequency
# XXX
return 0 return 0
...@@ -77,5 +80,44 @@ def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config ...@@ -77,5 +80,44 @@ def createSymlinksFromConfig(destination_folder_config_tuple, source_list_config
if e.errno != os.errno.EEXIST: if e.errno != os.errno.EEXIST:
raise raise
class Popen(subprocess.Popen):
def set_timeout(self, timeout):
self.set_timeout = None # assert we're not called twice
event = threading.Event()
killed = [False] # we just need a mutable
def t():
# do not call wait() or poll() because they're not thread-safe
if not event.wait(timeout) and self.returncode is None:
# race condition if waitpid completes just before the signal sent ?
self.terminate()
killed[0] = True
if event.wait(5):
return
if self.returncode is None:
self.kill() # same race as for terminate ?
t = threading.Thread(target=t)
t.daemon = True
t.start()
def isKilled():
event.set()
t.join()
return killed[0]
return isKilled
def executePath(path):
# XXX script_timeout could be passed as parameters
script_timeout = 3600 # in seconds
with open(os.devnull, 'r+') as f:
p = Popen(command, cwd=instance_path,
env=None if sys.platform == 'cygwin' else {},
stdin=f, stdout=f, stderr=subprocess.PIPE)
killed = p.set_timeout(script_timeout)
stderr = p.communicate()[1]
if killed():
return "Timed Out"
elif p.returncode:
return stderr.strip()
return None
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(main()) sys.exit(main())
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