plugins/*/*.css
plugins/*/*.js
plugins/*/*.html
+# myslice.ini* is not intended to be under git as it may contain keys and other specifics
+myslice.ini*
+# other junk
+foo.*
# this is gross; at the very least we need to logout()
# but most importantly there is a need to refine that test, since
# code==2 does not necessarily mean an expired session
- # del request.session['manifold']
- raise Exception, 'Error running query: %r' % result
+ # XXX only if we know it is the issue
+ del request.session['manifold']
+ # Flush django session
+ request.session.flush()
+ #raise Exception, 'Error running query: %r' % result
if result['code'] == 1:
print "WARNING"
def execute_query(request, query):
if not 'manifold' in request.session or not 'auth' in request.session['manifold']:
+ request.session.flush()
raise Exception, "User not authenticated"
manifold_api_session_auth = request.session['manifold']['auth']
return _execute_query(request, query, manifold_api_session_auth)
debug=False
#debug=True
-# add artificial delay in s
-debug_spin=0
-#debug_spin=1
-
# pretend the server only returns - empty lists to 'get' requests - this is to mimick
# misconfigurations or expired credentials or similar corner case situations
debug_empty=False
json_answer=json.dumps(result)
- # this is an artificial delay added for debugging purposes only
- if debug_spin>0:
- print "Adding additional artificial delay",debug_spin
- import time
- time.sleep(debug_spin)
-
return HttpResponse (json_answer, mimetype="application/json")
except Exception,e:
separator: '__',
- spin_presets: {},
-
- spin: function(locator, active /*= true */) {
- active = typeof active !== 'undefined' ? active : true;
- try {
- if (active) {
- $(locator).spin(manifold.spin_presets);
- } else {
- $(locator).spin(false);
- }
- } catch (err) { messages.debug("Cannot turn spins on/off " + err); }
- },
-
get_type: function(variable) {
switch(Object.toType(variable)) {
case 'number':
// reasonably low-noise, shows manifold requests coming in and out
asynchroneous_debug : true,
// print our more details on result publication and related callbacks
- publish_result_debug : false,
+ pubsub_debug : false,
/**
* \brief We use js function closure to be able to pass the query (array)
var publish_uuid=tuple.publish_uuid;
// by default we publish using the same uuid of course
if (publish_uuid==undefined) publish_uuid=query.query_uuid;
- if (manifold.publish_result_debug) {
+ if (manifold.pubsub_debug) {
messages.debug("sending POST on " + manifold.proxy_url + query.__repr());
}
// NEW PLUGIN API
manifold.raise_record_event(query.query_uuid, CLEAR_RECORDS);
- if (manifold.publish_result_debug)
+ if (manifold.pubsub_debug)
messages.debug(".. publish_result (1) ");
var count=0;
$.each(result, function(i, record) {
manifold.raise_record_event(query.query_uuid, NEW_RECORD, record);
count += 1;
});
- if (manifold.publish_result_debug)
- messages.debug(".. publish_result NEW API (2) count=" + count);
+ if (manifold.pubsub_debug)
+ messages.debug(".. publish_result (2) has used NEW API on " + count + " records");
manifold.raise_record_event(query.query_uuid, DONE);
+ if (manifold.pubsub_debug)
+ messages.debug(".. publish_result (3) has used NEW API to say DONE");
// OLD PLUGIN API BELOW
/* Publish an update announce */
var channel="/results/" + query.query_uuid + "/changed";
- if (manifold.publish_result_debug)
- messages.debug(".. publish_result OLD API (3) " + channel);
+ if (manifold.pubsub_debug)
+ messages.debug(".. publish_result (4) OLD API on channel" + channel);
$.publish(channel, [result, query]);
- if (manifold.publish_result_debug)
- messages.debug(".. publish_result - END (4) q=" + query.__repr());
+ if (manifold.pubsub_debug)
+ messages.debug(".. publish_result (5) END q=" + query.__repr());
},
/*!
* otherwise, publish the main object as well as subqueries
* XXX how much recursive are we ?
*/
- if (manifold.publish_result_debug)
+ if (manifold.pubsub_debug)
messages.debug (">>>>> publish_result_rec " + query.object);
if (manifold.query_expects_unique_result(query)) {
/* Also publish subqueries */
/* TODO remove object from result */
});
}
- if (manifold.publish_result_debug)
+ if (manifold.pubsub_debug)
messages.debug ("===== publish_result_rec " + query.object);
manifold.publish_result(query, result);
- if (manifold.publish_result_debug)
+ if (manifold.pubsub_debug)
messages.debug ("<<<<< publish_result_rec " + query.object);
},
}
if (manifold.asynchroneous_debug)
- messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records");
+ messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records [" + query.query_uuid +"]");
// once everything is checked we can use the 'value' part of the manifoldresult
var result=data.value;
**************************************************************************/
raise_event_handler: function(type, query_uuid, event_type, value) {
+ if (manifold.pubsub_debug)
+ messages.debug("raise_event_handler, quuid="+query_uuid+" type="+type+" event_type="+event_type);
if ((type != 'query') && (type != 'record'))
throw 'Incorrect type for manifold.raise_event()';
// xxx we observe quite a lot of incoming calls with an undefined query_uuid
- // this should be fixed upstream
+ // this should be fixed upstream in manifold I expect
if (query_uuid === undefined) {
messages.warning("undefined query in raise_event_handler");
return;
$.each(channels, function(i, channel) {
if (value === undefined) {
- $('.plugin').trigger(channel, [event_type]);
+ if (manifold.pubsub_debug) messages.debug("triggering [no value] on channel="+channel+" and event_type="+event_type);
+ $('.pubsub').trigger(channel, [event_type]);
} else {
- $('.plugin').trigger(channel, [event_type, value]);
+ if (manifold.pubsub_debug) messages.debug("triggering [value="+value+"] on channel="+channel+" and event_type="+event_type);
+ $('.pubsub').trigger(channel, [event_type, value]);
}
});
},
// reference and a normal reference
this.element = element;
this.$element = $(element);
+ // programmatically add specific class for publishing events
+ // used in manifold.js for triggering API events
+ if ( ! this.$element.hasClass('pubsub')) this.$element.addClass('pubsub');
// return this so we can chain/use the bridge with less code.
return this;
},
/* SPIN */
-
- spin: function() {
- manifold.spin(this.element);
+ // use spin() to get our default spin settings (called presets)
+ // use spin(true) to get spin's builtin defaults
+ // you can also call spin_presets() yourself and tweak what you need to, like topmenuvalidation does
+ spin: function (presets) {
+ var presets = ( presets === undefined ) ? spin_presets() : presets;
+ try { this.$element.spin(presets); }
+ catch (err) { messages.debug("Cannot turn on spin " + err); }
},
unspin: function() {
- manifold.spin(this.element, false);
+ try { this.$element.spin(false); }
+ catch (err) { messages.debug("Cannot turn off spin " + err); }
},
/* TEMPLATE */
if not os.path.isdir(ROOT): raise Exception,"Cannot find ROOT %s for unfold"%ROOT
if not os.path.isdir(HTTPROOT): raise Exception,"Cannot find HTTPROOT %s for unfold"%HTTPROOT
+# dec 2013 - we currently have 2 auxiliary subdirs with various utilities
+# that we do not wish to package
+# * sandbox is for plugin developers
+# * sample is for various test views
+# for each of these, if we find a directory of that name under ROOT, it then gets
+# inserted in INSTALLED_APPS and its urls get included (see urls.py)
+auxiliaries = [ 'sandbox', 'sample', ]
+
####################
ADMINS = (
# ('your_name', 'your_email@test.com'),
os.path.join(HTTPROOT,"templates"),
)
-INSTALLED_APPS = (
+INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'portal',
- # temporary - not packaged
- # 'trash',
- 'sample',
- 'sandbox'
-# DEPRECATED # 'django.contrib.formtools',
-# DEPRECATED ## 'crispy_forms',
-# DEPRECATED #
-# DEPRECATED # # User registration
-# DEPRECATED # 'django.contrib.auth',
-# DEPRECATED # 'django.contrib.sites',
-# DEPRECATED # 'registration',
-)
+]
+for aux in auxiliaries:
+ if os.path.isdir(os.path.join(ROOT,aux)):
+ print "Using devel auxiliary",aux
+ INSTALLED_APPS.append(aux)
ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.
from django.template.loader import add_to_builtins
add_to_builtins('insert_above.templatetags.insert_tags')
+from settings import auxiliaries, INSTALLED_APPS
+
import portal.platformsview
import portal.dashboardview
import portal.homeview
# might need another one ?
the_login_view=home_view
-urlpatterns = patterns(
+urls = [
'',
# Examples:
# url(r'^$', 'myslice.views.home', name='home'),
# url(r'^admin/', include(admin.site.urls)),
#
# default / view
- #
(r'^/?$', the_default_view),
#
# login / logout
- #
(r'^login-ok/?$', the_after_login_view, {'state': 'Welcome to MySlice'} ),
+ #
# seems to be what login_required uses to redirect ...
(r'^accounts/login/$', the_login_view),
(r'^login/?$', the_login_view),
(r'^logout/?$', 'auth.views.logout_user'),
#
# the manifold proxy
- #
(r'^manifold/proxy/(?P<format>\w+)/?$', 'manifold.manifoldproxy.proxy'),
#
# Portal
url(r'^portal/', include('portal.urls')),
- # Sandbox
- url(r'^sandbox/', include('sandbox.urls')),
- url(r'^sample/', include('sample.urls')),
- # Debug
-# url(r'^debug/', include('debug_platform.urls')),
- #
- # various trash views - bound to go away
- #
-# url(r'^trash/', include('trash.urls')),
+]
+
+#this one would not match the convention
+# url(r'^debug/', include('debug_platform.urls')),
+# but it was commented out anyways
+for aux in auxiliaries:
+ if aux in INSTALLED_APPS:
+ urls.append ( url ( r'^%s/'%aux, include ('%s.urls'%aux )))
-)
+urlpatterns = patterns(*urls)
def requirements (self):
# Some should be included by default by manifold
- return { 'js_files' : ['js/manifold.js', 'js/spin.presets.js', 'js/spin.min.js', 'js/jquery.spin.js',
+ return { 'js_files' : ['js/manifold.js', 'js/spin-presets.js', 'js/spin.min.js', 'js/jquery.spin.js',
'js/form.js', 'js/jquery.validate.js', ],
'css_files' : ['css/form.css']
}
"/js/googlemap.js",
"/js/markerclusterer.js",
"js/manifold.js", "js/manifold-query.js",
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/unfold-helper.js",
],
'css_files' : [ "css/googlemap.css",
this.by_id = {};
this.by_init_id = {};
- /* XXX Events */
+ /* Events */
+ // xx somehow non of these triggers at all for now
this.elmt().on('show', this, this.on_show);
- // TODO in destructor
- // $(window).unbind('QueryTable');
+ this.elmt().on('shown.bs.tab', this, this.on_show);
+ this.elmt().on('resize', this, this.on_resize);
var query = manifold.query_store.find_analyzed_query(this.options.query_uuid);
this.object = query.object;
if (debug) messages.debug("googlemap.on_show");
var googlemap = e.data;
google.maps.event.trigger(googlemap.map, 'resize');
- }, // on_show
+ },
+ // dummy to see if this triggers at all
+ on_resize: function(e) {
+ if (debug) messages.debug("googlemap.on_resize ...");
+ },
/* GUI EVENTS */
}
var domid = this.options.plugin_uuid + '--' + 'googlemap';
- var elmt = document.getElementById(domid);
- if (debug) messages.debug("gmap.initialize_map based on domid=" + domid + " elmt=" + elmt);
+ var elmt = document.getElementById(domid);
this.map = new google.maps.Map(elmt, myOptions);
this.infowindow = new google.maps.InfoWindow();
}, // initialize_map
/*************************** RECORD HANDLER ***************************/
on_new_record: function(record) {
- if (debug_deep) messages.debug("on_new_record");
+ if (debug_deep) messages.debug("googlemap.on_new_record");
if (this.received_all)
// update checkbox for record
this.set_checkbox_from_record(record, true);
},
on_clear_records: function(record) {
- if (debug_deep) messages.debug("on_clear_records");
+ if (debug_deep) messages.debug("googlemap.on_clear_records");
},
// Could be the default in parent
on_query_in_progress: function() {
- if (debug) messages.debug("on_query_in_progress (spinning)");
+ if (debug) messages.debug("googlemap.on_query_in_progress (spinning)");
this.spin();
},
on_query_done: function() {
- if (debug) messages.debug("on_query_done");
+ if (debug) messages.debug("googlemap.on_query_done");
if (this.received_all) {
this.unspin();
}
},
on_field_state_changed: function(data) {
- if (debug_deep) messages.debug("on_field_state_changed");
+ if (debug_deep) messages.debug("googlemap.on_field_state_changed");
switch(data.request) {
case FIELD_REQUEST_ADD:
case FIELD_REQUEST_ADD_RESET:
// all : this
on_all_new_record: function(record) {
- if (debug_deep) messages.debug("on_all_new_record");
+ if (debug_deep) messages.debug("googlemap.on_all_new_record");
this.new_record(record);
},
on_all_clear_records: function() {
- if (debug) messages.debug("on_all_clear_records");
+ if (debug) messages.debug("googlemap.on_all_clear_records");
},
on_all_query_in_progress: function() {
- if (debug) messages.debug("on_all_query_in_progress (spinning)");
+ if (debug) messages.debug("googlemap.on_all_query_in_progress (spinning)");
// XXX parent
this.spin();
},
on_all_query_done: function() {
- if (debug) messages.debug("on_all_query_done");
+ if (debug) messages.debug("googlemap.on_all_query_done");
// MarkerClusterer
var markers = [];
});
// reset
googlemap.in_set_backlog = [];
-
- if (debug) messages.debug("unspinning");
this.unspin();
}
this.received_all = true;
reqs = {
'js_files' : [ "js/simplelist.js",
"js/manifold.js", "js/manifold-query.js",
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/unfold-helper.js",
] ,
'css_files': [ "css/simplelist.css" ],
on_query_in_progress: function() {
messages.debug("on_query_in_progress");
- this.spin();
+ this.spin(true);
},
on_query_done: function() {
if (debug) messages.debug('datatables_update_table ' + rows.length + " rows");
$table.dataTable().fnClearTable();
// the lambda here returns a [[]] because $.map is kind of broken; as per the doc:
- // The function can return any value to add to the array. A returned array will be flattened into the resulting array.
+ // The function can return any value to add to the array.
+ // A returned array will be flattened into the resulting array.
// this is wrong indeed so let's work around that
var self=this;
$table.dataTable().fnAddData( $.map(rows, function (row) { return [[ self._cell (key,row[key]) ]] }) );
'js/jquery.tipsy.js',
'js/buffer.js', 'js/maddash.js',
'js/manifold.js', 'js/manifold-query.js',
- 'js/spin.presets.js', 'js/spin.min.js', 'js/jquery.spin.js',
+ 'js/spin-presets.js', 'js/spin.min.js', 'js/jquery.spin.js',
'js/unfold-helper.js',
],
'css_files' : [
'js_files' : [
"js/querycode.js",
"js/manifold.js", "js/manifold-query.js",
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/shAutoloader.js","js/shCore.js","js/shBrushPython.js","js/shBrushRuby.js",
] ,
# thierry: see this file for details of why we turn this off for now
def requirements (self):
reqs = {
'js_files' : [
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
# this one was in the slickgrid demo
# http://mleibman.github.io/SlickGrid/examples/example-checkbox-row-select.html
# but triggers js errors when included - probably/maybe because of the jquery version ?
def requirements (self):
reqs = {
- 'js_files' : [ "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ 'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js",
"js/manifold.js", "js/manifold-query.js",
"js/unfold-helper.js",
// an internal buffer for keeping lines and display them in one call to fnAddData
this.buffered_lines = [];
- /* XXX Events XXX */
- // this.$element.on('show.Datatables', this.on_show);
+ /* Events */
+ // xx somehow non of these triggers at all for now
this.elmt().on('show', this, this.on_show);
- // Unbind all events using namespacing
- // TODO in destructor
- // $(window).unbind('QueryTable');
+ this.elmt().on('shown.bs.tab', this, this.on_show);
+ this.elmt().on('resize', this, this.on_resize);
var query = manifold.query_store.find_analyzed_query(this.options.query_uuid);
this.object = query.object;
/* PLUGIN EVENTS */
- on_show: function(e)
- {
+ on_show: function(e) {
+ if (debug) messages.debug("querytable.on_show");
var self = e.data;
+ self.table.fnAdjustColumnSizing();
+ },
- self.table.fnAdjustColumnSizing()
-
- /* Refresh dataTabeles if click on the menu to display it : fix dataTables 1.9.x Bug */
- /* temp disabled... useful ? -- jordan
- $(this).each(function(i,elt) {
- if (jQuery(elt).hasClass('dataTables')) {
- var myDiv=jQuery('#querytable-' + this.id).parent();
- if(myDiv.height()==0) {
- var oTable=$('#querytable-' + this.id).dataTable();
- oTable.fnDraw();
- }
- }
- });
- */
- }, // on_show
+ on_resize: function(e) {
+ if (debug) messages.debug("querytable.on_resize");
+ var self = e.data;
+ self.table.fnAdjustColumnSizing();
+ },
/* GUI EVENTS */
result += " class='querytable-checkbox'";
// compute id from canonical_key
var id = record[this.canonical_key]
-// if (debug) messages.debug("checkbox_html, id="+id);
// compute init_id form init_key
var init_id=record[this.init_key];
// set id - for retrieving from an id, or for posting events upon user's clicks
set_checkbox_from_record: function (record, checked) {
if (checked === undefined) checked = true;
var init_id = record[this.init_key];
- if (debug) messages.debug("set_checkbox_from_record, init_id="+init_id);
+ if (debug) messages.debug("querytable.set_checkbox_from_record, init_id="+init_id);
// using table.$ to search inside elements that are not visible
var element = this.table.$('[init_id="'+init_id+'"]');
element.attr('checked',checked);
// id relates to canonical_key
set_checkbox_from_data: function (id, checked) {
if (checked === undefined) checked = true;
- if (debug) messages.debug("set_checkbox_from_data, id="+id);
+ if (debug) messages.debug("querytable.set_checkbox_from_data, id="+id);
// using table.$ to search inside elements that are not visible
var element = this.table.$("[id='"+id+"']");
element.attr('checked',checked);
// if the 'all' query has been dealt with already we may turn on the checkbox
this.set_checkbox_from_record(record, true);
} else {
- // otherwise we need to remember that and do it later on
- if (debug) messages.debug("Remembering record to check " + record[this.init_key]);
this.buffered_records_to_check.push(record);
}
},
// if we've already received the slice query, we have not been able to set
// checkboxes on the fly at that time (dom not yet created)
$.each(this.buffered_records_to_check, function(i, record) {
- if (debug) messages.debug ("delayed turning on checkbox " + i + " record= " + record);
+ if (debug) messages.debug ("querytable delayed turning on checkbox " + i + " record= " + record);
self.set_checkbox_from_record(record, true);
});
this.buffered_records_to_check = [];
#"//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js",
"js/raphael.js",
"js/manifold.js", "js/manifold-query.js",
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/unfold-helper.js",
"js/jquery-ui-timepicker-addon.js", "js/jquery-ui-sliderAccess.js",
],
def requirements (self):
reqs = {
'js_files' : [ "js/senslabmap.js",
- "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
"js/three.min.js", "js/jquery-mousewheel.min.js", "js/map.js",
],
'css_files': [ "css/senslabmap.css",
// storing tabs active component in localStorage
//
-// based on plugin_helper.js, extended to store the domid of an active tab
+// based on plugin-helper.js, extended to store the domid of an active tab
//
var tabs_helper = {
--- /dev/null
+from unfold.plugin import Plugin
+
+class TopmenuValidation (Plugin):
+
+ """This plugin is designed to work together with topmenu.
+
+It will check to see if user has PI rights at least on one authority,
+and if so will enable corresponding validation button in topmenu.
+
+A realistic example would have incoming query as
+
+Query.get('ple:user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
+
+"""
+
+ def __init__ (self, query=None, button_domid=None, **settings):
+ Plugin.__init__ (self, **settings)
+ # set defaults
+ if query is None:
+ query = Query.get('ple:user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
+ if button_domid is None: button_domid="topmenu-validate"
+ self.query=query
+ self.button_domid=button_domid
+
+ # this does not have any materialization
+ def render_content (self, request):
+ return ""
+
+ def requirements (self):
+ return { 'js_files': [ 'js/topmenuvalidation.js', 'js/manifold-query.js',
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ ], }
+
+ def json_settings_list (self):
+ return [ 'query_uuid', 'button_domid', ]
+
+#################### here is an extract previously in topmenu.py
+#import json
+#from pprint import pprint
+#from manifold.manifoldapi import execute_query
+#from manifold.core.query import Query
+### # ** Where am I a PI **
+### # For this we need to ask SFA (of all authorities) = PI function
+### user_query = Query().get('local:user').select('config','email')
+### user_details = execute_query(request, user_query)
+###
+### # Required: the user must have an authority in its user.config
+### # XXX Temporary solution
+### # not always found in user_details...
+### config={}
+#### Deactivated until fixed
+#### if user_details is not None:
+#### for user_detail in user_details:
+#### #email = user_detail['email']
+#### if user_detail['config']:
+#### config = json.loads(user_detail['config'])
+#### user_detail['authority'] = config.get('authority',"Unknown Authority")
+#### print "topmenu: %s", (user_detail['authority'])
+#### if user_detail['authority'] is not None:
+#### sub_authority = user_detail['authority'].split('.')
+#### root_authority = sub_authority[0]
+#### pi_authorities_query = Query.get(root_authority+':user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
+#### else:
+#### pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
+#### try:
+#### pi_authorities_tmp = execute_query(request, pi_authorities_query)
+#### except:
+#### pi_authorities_tmp = set()
+#### pi_authorities = set()
+#### for pa in pi_authorities_tmp:
+#### if 'pi_authorities' in pa:
+#### pi_authorities |= set(pa['pi_authorities'])
+#### print "pi_authorities =", pi_authorities
+#### if len(pi_authorities) > 0:
+#### result.append({'label':'Validation', 'href': '/portal/validate/'})
+### result.append({'label':'Validation', 'href': '/portal/validate/'})
--- /dev/null
+// first application is for the 'validation' button in the topmenu
+// if the subject query is non empty, then we turn on the subject button
+// that is provided through button_domid
+
+(function($){
+
+ var debug=false;
+// debug=true
+
+ var TopmenuValidation = Plugin.extend({
+
+ init: function(options, element) {
+ this._super(options, element);
+ this.listen_query(options.query_uuid);
+ this.triggered=false;
+ },
+
+ // Could be the default in parent
+ on_query_in_progress: function() {
+ var presets = spin_presets();
+ presets.radius=5;
+ presets.length=4;
+ presets.lines=7;
+ presets.width=2;
+ this.spin(presets);
+ },
+
+ // we have received at least one answer: we'll do something
+ on_new_record: function (record) {
+ // we only need to act on the first record
+ if (this.triggered) return;
+ $('#'+this.options.button_domid).removeClass('disabled');
+ this.unspin();
+ this.triggered=true;
+ },
+ // for reference only, since there is nothing we need to do at this point
+ on_query_done: function() {
+ if (!this.triggered) this.unspin();
+ },
+ });
+
+ $.plugin('TopmenuValidation', TopmenuValidation);
+
+})(jQuery);
pub_key_list = []
for platform_detail in platform_details:
- if 'sfa' in platform_detail['gateway_type'] and platform_detail['disabled']==0:
+ if 'sfa' in platform_detail['gateway_type']:
total_platform = platform_detail['platform']
total_platform_list.append(total_platform)
platform_access_list.append(platform_access)
# Removing the platform which already has access
+ print platform_access_list
+ print total_platform_list
for platform in platform_access_list:
+ print platform
total_platform_list.remove(platform)
# we could use zip. this one is used if columns have unequal rows
platform_list = [{'platform_no_access': t[0]}
+import json
from manifold.core.query import Query
+from manifold.manifoldapi import execute_query
+
from unfold.page import Page
from plugins.lists.testbedlist import TestbedList
#messages.info(self.request, 'You have logged in')
page = Page(self.request)
+ print "Dashboard page"
# Slow...
#slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
testbed_query = Query().get('network').select('network_hrn','platform')
# DEMO GEC18 Query only PLE
+ user_query = Query().get('local:user').select('config','email')
+ user_details = execute_query(self.request, user_query)
+
+ # not always found in user_details...
+ config={}
+ # for user_detail in user_details:
+ # #email = user_detail['email']
+ # if user_detail['config']:
+ # config = json.loads(user_detail['config'])
+ # user_detail['authority'] = config.get('authority',"Unknown Authority")
+#
+# print user_detail
+# if user_detail['authority'] is not None:
+# sub_authority = user_detail['authority'].split('.')
+# root_authority = sub_authority[0]
+# slice_query = Query().get(root_authority+':user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
+# else:
slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
page.enqueue_query(slice_query)
page.enqueue_query(testbed_query)
+import json
from django.template import RequestContext
from django.shortcuts import render_to_response
from unfold.page import Page
from manifold.core.query import Query, AnalyzedQuery
+from manifold.manifoldapi import execute_query
-from ui.topmenu import topmenu_items, the_user
+from ui.topmenu import topmenu_items_live, the_user
from plugins.raw import Raw
from plugins.stack import Stack
page.add_js_chunks ('$(function() { messages.debug("sliceview: leases turned %s"); });'%("on" if do_query_leases else "off"))
config=Config()
page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url()))
+
page.expose_js_metadata()
-
+
metadata = page.get_metadata()
resource_md = metadata.details_by_object('resource')
resource_fields = [column['name'] for column in resource_md['column']]
main_query_init_key = 'hostname'
query_resource_all = Query.get('resource').select(resource_fields)
- if do_query_users:
- query_user_all = Query.get('user').select(user_fields)
-
+
aq = AnalyzedQuery(main_query, metadata=metadata)
page.enqueue_query(main_query, analyzed_query=aq)
page.enqueue_query(query_resource_all)
if do_query_users:
- page.enqueue_query(query_user_all)
+ # Required: the user must have an authority in its user.config
+ # XXX Temporary solution
+ user_query = Query().get('local:user').select('config','email')
+ user_details = execute_query(self.request, user_query)
+
+ # not always found in user_details...
+ config={}
+# for user_detail in user_details:
+# #email = user_detail['email']
+# if user_detail['config']:
+# config = json.loads(user_detail['config'])
+# user_detail['authority'] = config.get('authority',"Unknown Authority")
+#
+# if user_detail['authority'] is not None:
+# sub_authority = user_detail['authority'].split('.')
+# root_authority = sub_authority[0]
+# query_user_all = Query.get(root_authority+':user').select(user_fields)
+#
+# # XXX TODO this filter doesn't work - to be improved in Manifold
+# #.filter_by('authority.authority_hrn', '=', user_detail['authority'])
+#
+# page.enqueue_query(query_user_all)
+# else:
+# print "authority of the user is not in local:user db"
+ query_user_all = Query.get('user').select(user_fields)
+ # query_user_all = None
# ... and for the relations
# XXX Let's hardcode resources for now
# --------------------------------------------------------------------------
# USERS
- if do_query_users:
+ if do_query_users and query_user_all is not None:
tab_users = Tabs(
page = page,
domid = 'users',
outline_complete = True,
))
-
# variables that will get passed to the view-unfold1.html template
template_env = {}
# more general variables expected in the template
template_env [ 'title' ] = '%(slicename)s'%locals()
# the menu items on the top
- template_env [ 'topmenu_items' ] = topmenu_items('Slice', request)
+ template_env [ 'topmenu_items' ] = topmenu_items_live('Slice', page)
# so we can sho who is logged
template_env [ 'username' ] = the_user (request)
from plugins.querygrid import QueryGrid
-class SimpleGridView (TemplateView):
+class QueryGridView (TemplateView):
def get (self, request, slicename='ple.inria.f14'):
from plugins.querytable import QueryTable
-class SimpleTableView (TemplateView):
+class QueryTableView (TemplateView):
def get (self, request, slicename='ple.inria.f14'):
--- /dev/null
+from django.core.context_processors import csrf
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+from django.contrib.auth.decorators import login_required
+
+from unfold.prelude import Prelude
+
+from ui.topmenu import topmenu_items, the_user
+# tmp
+from trash.trashutils import lorem, hard_wired_slice_names
+
+def scroll_view (request):
+ return render_to_response ('view-scroll.html',
+ {'title':'Toy page for scrolling',
+ 'topmenu_items': topmenu_items('scroll',request),
+ 'username':the_user (request),
+ 'lorem':lorem,
+ },
+ context_instance=RequestContext(request))
+
--- /dev/null
+from django.core.context_processors import csrf
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+from django.contrib.auth.decorators import login_required
+
+from unfold.prelude import Prelude
+
+from ui.topmenu import topmenu_items, the_user
+# tmp
+from trash.trashutils import lorem, hard_wired_slice_names
+
+@login_required
+def tab_view (request):
+ print "request", request.__class__
+ print request
+ prelude=Prelude( js_files='js/bootstrap.js', css_files='css/bootstrap.css')
+ prelude_env = prelude.prelude_env()
+
+ tab_env = {'title':'Page for playing with Tabs',
+ 'topmenu_items': topmenu_items('tab',request),
+ 'username':the_user (request),
+ 'lorem': lorem,
+ }
+ tab_env.update (prelude_env)
+ return render_to_response ('view-tab.html', tab_env,
+ context_instance=RequestContext(request))
+
--- /dev/null
+# just one instance of validator
+from django.views.generic.base import TemplateView
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+
+from manifold.core.query import Query, AnalyzedQuery
+
+from unfold.page import Page
+
+from ui.topmenu import topmenu_items_live, the_user
+
+class TopmenuValidationView (TemplateView):
+
+ # mention a user name in the URL as .../trash/simpletopmenuvalidation/ple.inria.thierry_parmentelat
+ def get (self, request, username='ple.inria.thierry_parmentelat'):
+
+ if username=='logged': username='$user_hrn'
+
+ page=Page(request)
+
+ # variables that will get passed to the view-unfold1.html template
+ template_env = {}
+
+ # write something of our own instead
+ template_env ['unfold_main'] = '<h1>Some title </h1>'
+
+ # more general variables expected in the template
+ template_env [ 'title' ] = 'simple topmenuvalidation %(username)s'%locals()
+ # the menu items on the top
+ template_env [ 'topmenu_items' ] = topmenu_items_live('Slice', page)
+ # so we can see who is logged
+ template_env [ 'username' ] = the_user (request)
+
+ # don't forget to run the requests
+ page.expose_queries ()
+
+ # the prelude object in page contains a summary of the requirements() for all plugins
+ # define {js,css}_{files,chunks}
+ prelude_env = page.prelude_env()
+
+# print prelude_env.keys()
+# for k in [ 'js_files' ] :
+# print 'prelude_env',prelude_env,k,prelude_env[k]
+
+ template_env.update(prelude_env)
+ result=render_to_response ('view-unfold1.html',template_env,
+ context_instance=RequestContext(request))
+ return result
#
# Authors:
# Jordan Augé <jordan.auge@lip6.fr>
+# thierry.parmentelat@inria.fr
# Copyright 2013, UPMC Sorbonne Universités / LIP6
#
# This program is free software; you can redistribute it and/or modify it under
from django.conf.urls import patterns, url
from sample.views import WebSocketsView, WebSockets2View
-urlpatterns = patterns('',
- url(r'^websockets/?$', WebSocketsView.as_view(), name='websockets'),
- url(r'^websockets2/?$', WebSockets2View.as_view(), name='websockets2'),
+import sample.querytableview
+import sample.querygridview
+import sample.topmenuvalidationview
+
+urlpatterns = patterns(
+ '',
+ url(r'^websockets/?$', WebSocketsView.as_view(), name='websockets'),
+ url(r'^websockets2/?$', WebSockets2View.as_view(), name='websockets2'),
+ url(r'^tab/?$', 'sample.tabview.tab_view'),
+ url(r'^scroll/?$', 'sample.scrollview.scroll_view'),
+ url(r'^plugin/?$', 'sample.pluginview.test_plugin_view'),
+ url(r'^dashboard/?$', 'sample.dashboardview.dashboard_view'),
+ url(r'^querytable/(?P<slicename>[\w\.]+)/?$', sample.querytableview.QueryTableView.as_view()),
+ url(r'^querygrid/(?P<slicename>[\w\.]+)/?$', sample.querygridview.QueryGridView.as_view()),
+ url(r'^topmenuvalidation/(?P<username>[\w\._]+)/?$', sample.topmenuvalidationview.TopmenuValidationView.as_view()),
)
+++ /dev/null
-# Create your views here.
-from django.core.context_processors import csrf
-from django.template import RequestContext
-from django.shortcuts import render_to_response
-from django.contrib.auth.decorators import login_required
-
-from unfold.prelude import Prelude
-
-from ui.topmenu import topmenu_items, the_user
-# tmp
-from trash.trashutils import lorem, hard_wired_slice_names
-
-@login_required
-def tab_view (request):
- print "request", request.__class__
- print request
- prelude=Prelude( js_files='js/bootstrap.js', css_files='css/bootstrap.css')
- prelude_env = prelude.prelude_env()
-
- tab_env = {'title':'Page for playing with Tabs',
- 'topmenu_items': topmenu_items('tab',request),
- 'username':the_user (request),
- 'lorem': lorem,
- }
- tab_env.update (prelude_env)
- return render_to_response ('view-tab.html', tab_env,
- context_instance=RequestContext(request))
-
-def scroll_view (request):
- return render_to_response ('view-scroll.html',
- {'title':'Toy page for scrolling',
- 'topmenu_items': topmenu_items('scroll',request),
- 'username':the_user (request),
- 'lorem':lorem,
- },
- context_instance=RequestContext(request))
-
-@login_required
-def test_plugin_view (request):
-
- page = Page(request)
-
- # variables that will get passed to this template
- template_env = {}
-
- main_plugin = \
- Stack ( page=page,
- title='title for the vertical layout',
- sons = [ StaticList (page=page,
- title='StaticList - with datatables - starts toggled off',
- list=hard_wired_list,
- header='Hard wired header',
- foo='the value for foo',
- with_datatables=True,
- toggled=False),
- Tabs (page=page,
- title='Sample Tabs',
- domid='test-tabs',
- # *** we select this one to be the active tab ***
- active_domid='son2',
- sons = [ Raw (page=page,
- title='a raw plugin',
- domid='son0',
- togglable=False,
- html= 3*lorem_p,
- ),
- StaticList(page=page,
- title='a slice list',
- domid='son1',
- togglable=False,
- header="static list but not togglable",
- list=hard_wired_slice_names,
- ),
- Raw (page=page,
- title='raw title',
- domid='son2',
- togglable=False,
- html=lorem) ]),
- StaticList (page=page,
- title='SimpleList with slice names',
- list=hard_wired_slice_names,
- ),
- QuickFilter (page=page,
- title='QuickFilter in main content',
- criterias=quickfilter_criterias,
- ) ] )
- # define 'unfold_main' to the template engine
- template_env [ 'unfold_main' ] = main_plugin.render(request)
-
- ##########
- related_plugin = StaticList (page=page,
- title='SliceList plugin',domid='slicelist1',
- with_datatables='yes',
- list=hard_wired_slice_names,
- header='Slices')
- # likewise but on the side view
- template_env [ 'unfold_margin' ] = related_plugin.render (request)
-
- # more general variables expected in the template
- template_env [ 'title' ] = 'Test Plugin View'
- template_env [ 'topmenu_items' ] = topmenu_items('plugin', request)
- template_env [ 'username' ] = the_user (request)
-
- # we don't have anythong asynchroneous, and manifold.js is not loaded
-# page.expose_queries ()
-
- # the prelude object in page contains a summary of the requirements() for all plugins
- # define {js,css}_{files,chunks}
- prelude_env = page.prelude_env()
- template_env.update(prelude_env)
- return render_to_response ('view-unfold2.html',template_env,
- context_instance=RequestContext(request))
-
+++ /dev/null
-from django.conf.urls import patterns, include, url
-
-import trash.simpletableview
-import trash.simplegridview
-
-urlpatterns = patterns(
- '',
- url(r'^tab/?$', 'trash.sampleviews.tab_view'),
- url(r'^scroll/?$', 'trash.sampleviews.scroll_view'),
- url(r'^plugin/?$', 'trash.pluginview.test_plugin_view'),
- url(r'^dashboard/?$', 'trash.dashboard.dashboard_view'),
- url(r'^simpletable/(?P<slicename>[\w\.]+)/?$', trash.simpletableview.SimpleTableView.as_view()),
- url(r'^simplegrid/(?P<slicename>[\w\.]+)/?$', trash.simplegridview.SimpleGridView.as_view()),
-)
{% insert_str prelude "js/jquery.html5storage.min.js" %}
{% insert_str prelude "js/messages-runtime.js" %}
{% insert_str prelude "js/class.js" %}
-{% insert_str prelude "js/plugin_helper.js" %}
+{% insert_str prelude "js/plugin-helper.js" %}
{% insert_str prelude "js/mustache.js" %}
{% insert_str prelude "js/plugin.js" %}
{% insert_str prelude "js/manifold.js" %}
<a class="dropdown-toggle" data-toggle="dropdown" href="{{ d.href }}">{{ d.label }}<b class="caret"></b></a>
<ul class="dropdown-menu">
{% for dd in d.contents %}
- {% if dd.is_active %}<li class='active'>{% else %}<li class='other'>{% endif %}
+ <li class='{% if dd.is_active %}active{% else %}other{% endif %}{% if dd.disabled %} disabled{%endif%}'
+ {% if dd.domid %} id='{{dd.domid}}'{% endif %}>
<a href="{{ dd.href }}"> {{ dd.label }} </a> </li>
{% endfor %}
</ul>
</li>
{% else %}
- {% if d.is_active %} <li class='active'> {% else %} <li class='other'> {% endif %}
+ <li class='{% if d.is_active %}active{% else %}other{% endif %}{% if d.disabled %} disabled{%endif%}'
+ {% if d.domid %} id='{{d.domid}}'{% endif %}>
<a href="{{ d.href }}"> {{ d.label }} </a> </li>
{% endif %}
{% endfor %}
-from pprint import pprint
-from manifold.manifoldapi import execute_query
-from manifold.core.query import Query
# a set of utilities to help make the global layout consistent across views
+def the_user (request):
+ "retrieves logged in user's email, or empty string"
+ if not request.user.is_authenticated ():
+ return ''
+ else:
+ return request.user.email
+
# dropdowns are kind of ad hoc for now, and limited to one level
# [
# ### a regular first-level button
-# {'label':...,'href':...},
+# {'label':...,'href':..., ['domid':.., 'disabled':...]},
# ### a dropdown
# { 'label': ..., 'href'=..., 'dropdown':True, 'contents': [ { 'label':.., 'href'} ] }
# , ..]
+# see also templates/widget-topmenu.html for how these items are put together
+# and plugins/topmenuvalidation for how this hident button is turned on when necessary
+
# current: the beginning of the label in the menu that you want to outline
-def topmenu_items (current,request=None):
+def topmenu_items_static (current, request):
has_user=request.user.is_authenticated()
result=[]
+ print request.user
if has_user:
result.append({'label':'Dashboard', 'href': '/portal/dashboard/'})
result.append({'label':'Request a slice', 'href': '/portal/slice_request/'})
- # ** Where am I a PI **
- # For this we need to ask SFA (of all authorities) = PI function
- pi_authorities_query = Query.get('ple:user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
- try:
- pi_authorities_tmp = execute_query(request, pi_authorities_query)
- except:
- pi_authorities_tmp = set()
- pi_authorities = set()
- for pa in pi_authorities_tmp:
- pi_authorities |= set(pa['pi_authorities'])
- print "pi_authorities =", pi_authorities
- if len(pi_authorities) > 0:
- result.append({'label':'Validation', 'href': '/portal/validate/'})
+ # always create a disabled button for validation, and let the
+ # topmenuvalidation plugin handle that asynchroneously, based on this domid
+ result.append({'label':'Validation', 'href': '/portal/validate/', 'domid':'topmenu-validation', 'disabled':True})
dropdown = []
dropdown.append({'label':'Platforms', 'href': '/portal/platforms/'})
dropdown.append({'label':'My Account', 'href': '/portal/account/'})
result.append({'label':'Platforms', 'href': '/portal/platforms/'})
result.append({'label':'Register', 'href': '/portal/register/'})
result.append({'label':'Contact Support', 'href': '/portal/contact/'})
+
# mark active if the provided 'current', even if shorter, matches the beginning of d['label']
-
if current is not None:
current=current.lower()
curlen=len(current)
for dd in d['contents']: mark_active(dd,d)
return result
-def the_user (request):
- "retrieves logged in user's email, or empty string"
- if not request.user.is_authenticated ():
- return ''
- else:
- return request.user.email
+# tmp - transition phase
+def topmenu_items (current, request):
+ print "WARNING -- please now use topmenu_items_live (label, page) toplevel_items is deprecated -- WARNING"
+ return topmenu_items_static (current, request)
+
+# integrated helper function for an animated menu
+from unfold.page import Page
+from manifold.core.query import Query
+from plugins.topmenuvalidation import TopmenuValidation
+
+### this is now the 'live' version, that has plugins
+# for asynchronous management of topmenu
+def topmenu_items_live (current, page):
+ request=page.request
+ query_pi_auths = Query.get('ple:user').filter_by('user_hrn', '==', '$user_hrn' ).select('pi_authorities')
+ page.enqueue_query(query_pi_auths)
+# # even though this plugin does not have any html materialization, the corresponding domid
+# # must exist because it is searched at init-time to create the JS plugin
+# # so we simply piggy-back the target button created in the topmenu
+ topmenuvalidation = TopmenuValidation (
+ page=page,
+ # see above
+ domid='topmenu-validation',
+ query=query_pi_auths,
+ # this one is the target for a $.show() when the query comes back
+ button_domid="topmenu-validation")
+ # although the result does not matter, rendering is required for the JS init code to make it in the page
+ topmenuvalidation.render(request)
+
+ return topmenu_items_static (current, request)
+
def expose_js_metadata (self):
# expose global MANIFOLD_METADATA as a js variable
# xxx this is fetched synchroneously..
- self.add_js_init_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";")
+ self.add_js_init_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";\n")
def expose_js_manifold_config (self):
config=Config()
-var spin_presets={
+function spin_presets() { return {
lines: 13, // The number of lines to draw
length: 7, // The length of each line
width: 4, // The line thickness
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
color: '#f00', // #rgb or #rrggbb
- speed: 0.3, // Rounds per second
+ speed: 0.7, // Rounds per second
trail: 60, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: true, // Whether to use hardware acceleration
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: 'auto', // Top position relative to parent in px
left: 'auto' // Left position relative to parent in px
-};
+}}