find_query : function (query_uuid) {
return manifold.all_queries[query_uuid];
},
- debug_all_queries : function (msg) {
- for (var query_uuid in manifold.all_queries) {
- messages.debug("manifold.debug " + msg + " " + query_uuid + " -> " + manifold.all_queries[query_uuid]);
- }
- },
// trigger a query asynchroneously
proxy_url : '/manifold/proxy/json/',
// however in some cases we wish to publish the results under a different uuid
// e.g. an updater wants to publish its results as if from the original (get) query
asynchroneous_success : function (data, query, publish_uuid, domid) {
- if (manifold.asynchroneous_debug) messages.debug("received manifold result with code " + data.code);
+ if (manifold.asynchroneous_debug)
+ messages.debug("received manifold result with code " + data.code + " for publish on " + publish_uuid);
// xxx should have a nicer declaration of that enum in sync with the python code somehow
if (data.code == 1) {
alert("Your session has expired, please log in again");
window.location="/logout/";
return;
} else if (data.code != 0) {
- alert("Error received from manifold backend at " + MANIFOLD_URL + " [" + data.output + "]");
+ messages.error("Error received from manifold backend at " + MANIFOLD_URL + " [" + data.output + "]");
+ // publish error code and text message on a separate channel for whoever is interested
+ jQuery.publish("/results/" + publish_uuid + "/failed", [data.code, data.output] );
return;
}
// once everything is checked we can use the 'value' part of the manifoldresult
- data=data.value;
- if (data) {
+ var value=data.value;
+ if (value) {
if (!!domid) {
/* Directly inform the requestor */
if (manifold.asynchroneous_debug) messages.debug("directing results to " + domid);
- jQuery('#' + domid).trigger('results', [data]);
+ jQuery('#' + domid).trigger('results', [value]);
} else {
/* Publish an update announce */
if (manifold.asynchroneous_debug) messages.debug("publishing results on " + publish_uuid);
- jQuery.publish("/results/" + publish_uuid + "/changed", [data, query]);
+ jQuery.publish("/results/" + publish_uuid + "/changed", [value, query]);
}
}
# until we have some agreement about how the API calls should return error conditions
# in some less unpolite way than this anonymous exception, we assume it's a problem with the session
# that needs to be refreshed
- if debug: print "Session Expired"
if error.faultCode == 8002:
reason="most likely your session has expired"
reason += " (the manifold API has no unambiguous error reporting mechanism yet)"
return ManifoldResult (code=ManifoldCode.SESSION_EXPIRED, output=reason)
+ else:
+ reason="xmlrpclib.Fault with faultCode = %s (not taken as session expired)"%error.faultCode
+ return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output=reason)
except Exception,error:
print "ManifoldAPI: unexpected exception",error
- return ManifoldResult (code=ManifoldResult.UNKNOWN_ERROR, output="%s"%error)
+ return ManifoldResult (code=ManifoldCode.UNKNOWN_ERROR, output="%s"%error)
return func
def send_manifold_query (self, query):
(action,subject)= (query.action,query.subject)
- # use e.g. self.Get rather than self.server.Get so we catch exceptions as per __getattr__
+ # use e.g. self.Get rather than self.server.Get so we use the __getattr__ code
if action=='get':
# this makes the backend to squeak and one can't login anymore...
# return self.Get(subject, query.filters, query.timestamp, query.fields)
return self.Get(subject, query.filters, {}, query.fields)
- if action=='update':
- return self.Update(subject, query.filters, query.params, query.fields)
+ elif action=='update':
+ answer=self.Update(subject, query.filters, query.params, query.fields)
+ if not isinstance (answer, ManifoldResult): print "UNEXECPECTED answer", answer
+ return answer
else:
warning="WARNING: ManifoldAPI.send_manifold_query: %s not implemented for now"%action
print warning
+ print 3
return ManifoldResult(code=ManifoldCode.NOT_IMPLEMENTED, output=warning)
self.subqueries = {}
def __repr__ (self):
- result="Q: id=%(query_uuid)s - %(action)s on %(subject)s "%self.__dict__
+ result="[[Q: id=%(query_uuid)s - %(action)s on %(subject)s "%self.__dict__
result += " with %d filters, %d fields"%(len(self.filters),len(self.params))
+ result += "]]"
return result
def to_json (self):
SUCCESS=0,
SESSION_EXPIRED=1,
NOT_IMPLEMENTED=2,
- OTHERS=3,
+ UNKNOWN_ERROR=3,
)
# being a dict this can be used with json.dumps
def error (self):
return "code=%s -- %s"%(self['code'],self['output'])
+
+ def __repr__ (self):
+ result="[[MFresult code=%s"%self['code']
+ if self['code']==0:
+ value=self['value']
+ if isinstance(value,list): result += " [value=list with %d elts]"%len(value)
+ else: result += " [value=other %s]"%value
+ else:
+ result += " [output=%s]"%self['output']
+ result += "]]"
+ return result
var update_channel = '/update-set/' + options.query_uuid;
var results_channel = '/results/' + options.query_uuid + '/changed';
+ // xxx not tested yet
$.subscribe(query_channel, function(e, query) { hazelnut.set_query(query); });
+ // xxx not tested yet
$.subscribe(update_channel, function(e, resources, instance) { hazelnut.set_resources(resources, instance); });
+ // expected to work
$.subscribe(results_channel, $this, function(e, rows) { hazelnut.update_plugin(e,rows); });
if (debug) messages.debug("hazelnut '" + this.id + "' subscribed to e.g." + results_channel);
def __init__ (self, query, **settings):
Plugin.__init__ (self, **settings)
self.query=query
- # our javascript requires the details of the manifold server
- self.page.expose_js_manifold_config()
def template_file (self):
return "querycode.html"
( function ( $ ) {
+ var debug=false;
+// debug=true
+
$.fn.Updater = function ( method ) {
/* Method calling logic */
if ( methods[method] ) {
var $this = $(this);
var updater = new Updater (options);
$this.data('Updater',updater);
- /* Subscribe to query updates */
+ // xxx not tested yet
var results_channel = '/results/' + options.query_uuid + '/changed';
- $.subscribe(results_channel, function (e,rows) { updater.update_slice (e,rows); } );
+ $.subscribe(results_channel, function (e,rows) { updater.query_completed (e,rows); } );
+ // under test..
+ var failed_channel = '/results/' + options.query_uuid + '/failed';
+ $.subscribe(failed_channel, $this, function (e,code,output) { updater.query_failed (e, code, output); } );
});
},
destroy : function( ) {
// implementation wouldn't fly
// we keep this for a later improvement
var query=manifold.find_query (options.query_uuid);
- messages.info("retrieved query " + query.__repr());
// very rough way of filling this for now
this.update_query =
new ManifoldQuery ("update", query.subject, null, query.filters,
$('#updater-' + this.options.plugin_uuid).click(this, this.submit_update_request);
},
this.submit_update_request = function (e) {
- messages.debug("submit_update_request");
var query_uuid = e.data.options.query_uuid;
var update_query = e.data.update_query;
- messages.debug("Updater.submit_update_request " + update_query.__repr());
+ if (debug) messages.debug("Updater.submit_update_request " + update_query.__repr());
// actually send the Update query, but publish results as if coming from the original query
- manifold.asynchroneous_exec ( [ {'query_uuid': update_query.query_uuid, 'publish_uuid' : query_uuid} ]);
- // looks like a previous attempt to disable the button while the query is flying
- //$('#updateslice-' + options.plugin_uuid).prop('disabled', true);
+ manifold.asynchroneous_exec ( [ {'query_uuid': update_query.query_uuid, 'publish_uuid' : query_uuid} ], false);
+ // disable button while the query is flying
+ $('#updater-' + e.data.options.plugin_uuid).attr('disabled', 'disabled');
},
+ this.query_failed = function (e, code, output) {
+ var plugindiv=e.data;
+ var updater=plugindiv.data('Updater');
+ $('#updater-' + updater.options.plugin_uuid).removeAttr('disabled');
+ // just as a means to deom how to retrieve the stuff passed on the channel
+ if (debug) messages.debug("retrieved error code " + code + " and output " + output);
+ }
+
update_resources = function (e, resources, change) {
data = e.data.instance.data().Slices;
$.publish('/update/' + data.options.query_uuid, [data.update_query, true]);
},
- update_slice = function (e, rows, query) {
+
- /* This function is called twice : get and update */
+ query_completed = function (e, rows, query) {
+ /* This function is called twice : get and update */
+ messages.info("updater.query_completed - not implemented yet");
var data = e.data.instance.data().Slices;
def __init__ (self, query, label="Update", **settings):
Plugin.__init__ (self, **settings)
- # xxx would make sense to check this is a Get query...
self.query=query
+ if query.action != "get": print "Updater on non-get query: ",query.action
self.label=label
def template_file (self):
# although this has no query, we need a plugin instance to be created in the js output
def export_json_settings (self): return True
# the js plugin expects a domid
- def json_settings_list (self): return [ 'plugin_uuid', 'query_uuid' ]
+ def json_settings_list (self): return [ 'plugin_uuid', 'query_uuid', ]
# and we don't need a spin wheel
def start_with_spin (self): return False
from plugins.tabs.tabs import Tabs
from plugins.lists.staticlist import StaticList
from plugins.quickfilter.quickfilter import QuickFilter
+from plugins.querycode.querycode import QueryCode
from plugins.raw.raw import Raw
from plugins.messages.messages import Messages
from plugins.hazelnut.hazelnut import Hazelnut
slicename='ple.inria.omftest'
main_query = ManifoldQuery (action='get',
- subject='resource',
+ subject='slice',
timestamp='latest',
fields=['network','type','hrn','hostname'],
filters= [ [ 'slice_hrn', '=', slicename, ] ],
return result
env['query_publish_dom_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ]
javascript = render_to_string ("page-queries.js",env)
-# self.reset_queue()
self.add_js_chunks (javascript)
+# self.reset_queue()
+ # unconditionnally expose MANIFOLD_URL, this is small and manifold.js uses that for various messages
+ self.expose_js_manifold_config()
# needs to be called explicitly and only when metadata is actually required