From: Loic Baron Date: Thu, 24 Oct 2013 23:58:01 +0000 (+0200) Subject: Merge branch 'master' of ssh://git.onelab.eu/git/myslice X-Git-Tag: 0.2-6~6^2^2~1 X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=commitdiff_plain;h=fea9b7e286cc86f11844e371d67d184198afc287;hp=7c9892a134c74fba4de425609e392a99c7de4d71 Merge branch 'master' of ssh://git.onelab.eu/git/myslice --- diff --git a/apache/myslice.conf b/apache/myslice.conf index 9e8a1551..b7824520 100644 --- a/apache/myslice.conf +++ b/apache/myslice.conf @@ -1,7 +1,7 @@ - WSGIScriptAlias / /usr/share/unfold/apache/myslice.wsgi - - + WSGIScriptAlias / /usr/share/unfold/myslice/wsgi.py + + Order deny,allow Allow from all diff --git a/debian/unfold.install b/debian/unfold.install index 4f3996ed..a86e983a 100644 --- a/debian/unfold.install +++ b/debian/unfold.install @@ -12,4 +12,3 @@ usr/share/unfold/trash usr/share/unfold/debug_platform manage.py usr/share/unfold/ apache/myslice.conf /etc/apache2/sites-available -apache/myslice.wsgi usr/share/unfold/apache diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index c00882ae..e7c6ce90 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -20,13 +20,13 @@ class ManifoldAPI: def __init__(self, auth=None, cainfo=None): - config = Config() self.auth = auth self.cainfo = cainfo self.errors = [] self.trace = [] self.calls = {} self.multicall = False + config = Config() self.url = config.manifold_url() self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True) diff --git a/manifold/static/js/manifold.js b/manifold/static/js/manifold.js index c4d0ef73..11fad7da 100644 --- a/manifold/static/js/manifold.js +++ b/manifold/static/js/manifold.js @@ -738,7 +738,7 @@ var manifold = { expires: false, speed: 1000 }); -*/ +*/ } if (manifold.asynchroneous_debug) messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records"); diff --git a/myslice/config.py b/myslice/config.py index 31dc7e31..53295c4a 100644 --- a/myslice/config.py +++ b/myslice/config.py @@ -2,15 +2,19 @@ import os.path from ConfigParser import RawConfigParser from myslice.settings import ROOT -# myslice/myslice.ini -# as this code suggests, you have the option to write myslice/myslice.ini +# as this code suggests, you have the option to override these defaults +# by writing a file myslice/myslice.ini # that looks like this #[manifold] #url = http://manifold.pl.sophia.inria.fr:7080/ #admin_user = admin #admin_password = admin -class Config: +# use a singleton instead of staticmethods +from manifold.util.singleton import Singleton + +class Config(object): + __metaclass__ = Singleton # the OpenLab-wide backend as managed by UPMC # xxx production should probably use https of course @@ -20,40 +24,25 @@ class Config: # the INRIA setup is with "http://manifold.pl.sophia.inria.fr:7080/" default_manifold_admin_user = 'admin' - default_manifold_admin_password = None - - _config_parser = None - - # having grown tired of screwing up with git stashes - # taking away my local config, we now more properly use - # an external config file to override teh default - # XXX we might use support from manifold util classes --jordan - @staticmethod - def manifold_url (): - if Config._config_parser: - return Config._config_parser.get('manifold','url') - config = RawConfigParser () - config.add_section('manifold') - config.set ('manifold', 'url', Config.default_manifold_url) - config.read (os.path.join(ROOT,'myslice/myslice.ini')) - Config._config_parser=config - return Config.manifold_url() - - @staticmethod - def manifold_admin_user_password(): - if Config._config_parser: - admin_user = Config._config_parser.get('manifold','admin_user') - admin_password = Config._config_parser.get('manifold','admin_password') - return (admin_user, admin_password) - config = RawConfigParser () - config.add_section('manifold') - config.set ('manifold', 'admin_user', Config.default_manifold_admin_user) - config.set ('manifold', 'admin_password', Config.default_manifold_admin_password) - config.read (os.path.join(ROOT,'myslice/myslice.ini')) - Config._config_parser=config - return Config.manifold_admin_user_password() + default_manifold_admin_password = 'demo' + + + def __init__ (self): + parser = RawConfigParser () + parser.add_section('manifold') + parser.set ('manifold', 'url', Config.default_manifold_url) + parser.set ('manifold', 'admin_user', Config.default_manifold_admin_user) + parser.set ('manifold', 'admin_password', Config.default_manifold_admin_password) + parser.read (os.path.join(ROOT,'myslice/myslice.ini')) + self.config_parser=parser + + def manifold_url (self): + return self.config_parser.get('manifold','url') + + def manifold_admin_user_password(self): + return (self.config_parser.get('manifold','admin_user'), + self.config_parser.get('manifold','admin_password')) # exporting these details to js - @staticmethod - def manifold_js_export (): - return "var MANIFOLD_URL = '%s';\n"%Config.manifold_url(); + def manifold_js_export (self): + return "var MANIFOLD_URL = '%s';\n"%self.manifold_url(); diff --git a/myslice/myslice.ini b/myslice/myslice.ini.localhost similarity index 100% rename from myslice/myslice.ini rename to myslice/myslice.ini.localhost diff --git a/apache/myslice.wsgi b/myslice/wsgi.py similarity index 100% rename from apache/myslice.wsgi rename to myslice/wsgi.py diff --git a/plugins/myplugin/__init__.py b/plugins/myplugin/__init__.py index ce8e9392..685407dd 100644 --- a/plugins/myplugin/__init__.py +++ b/plugins/myplugin/__init__.py @@ -1,6 +1,10 @@ from unfold.plugin import Plugin class MyPlugin(Plugin): + + def __init__ (self, query, **settings): + Plugin.__init__ (self, **settings) + self.query=query def template_file (self): return "myplugin.html" @@ -17,7 +21,10 @@ class MyPlugin(Plugin): return reqs def json_settings_list (self): - return ['plugin_uuid', 'domid'] + # query_uuid will pass self.query results to the javascript + # and will be available as "record" in : + # on_new_record: function(record) + return ['plugin_uuid', 'domid', 'query_uuid'] def export_json_settings (self): return True diff --git a/plugins/slicestat/__init__.py b/plugins/slicestat/__init__.py new file mode 100644 index 00000000..dadebd01 --- /dev/null +++ b/plugins/slicestat/__init__.py @@ -0,0 +1,29 @@ +from unfold.plugin import Plugin + +class SliceStat(Plugin): + + def __init__ (self, query, **settings): + Plugin.__init__ (self, **settings) + self.query=query + + def template_file (self): + return "slicestat.html" + + def requirements (self): + reqs = { + 'js_files' : [ + + 'js/slicestat.js', + + ], + 'css_files': [ + 'css/slicestat.css', + ] + } + return reqs + + def json_settings_list (self): + return ['plugin_uuid', 'domid', 'query_uuid'] + + def export_json_settings (self): + return True diff --git a/plugins/slicestat/static/css/slicestat.css b/plugins/slicestat/static/css/slicestat.css new file mode 100644 index 00000000..9962c83b --- /dev/null +++ b/plugins/slicestat/static/css/slicestat.css @@ -0,0 +1,6 @@ +iframe#slicestat_resource { + width:100%; + height:400px; + border:0; + overflow: hidden; +} diff --git a/plugins/slicestat/static/js/date.js b/plugins/slicestat/static/js/date.js new file mode 100644 index 00000000..77f49864 --- /dev/null +++ b/plugins/slicestat/static/js/date.js @@ -0,0 +1,104 @@ +/** + * Version: 1.0 Alpha-1 + * Build Date: 13-Nov-2007 + * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved. + * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. + * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/ + */ +Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}}; +Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;idate)?1:(this=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;} +var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);} +if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);} +if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);} +if(x.hour||x.hours){this.addHours(x.hour||x.hours);} +if(x.month||x.months){this.addMonths(x.month||x.months);} +if(x.year||x.years){this.addYears(x.year||x.years);} +if(x.day||x.days){this.addDays(x.day||x.days);} +return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(valuemax){throw new RangeError(value+" is not a valid value for "+name+".");} +return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;} +if(!x.second&&x.second!==0){x.second=-1;} +if(!x.minute&&x.minute!==0){x.minute=-1;} +if(!x.hour&&x.hour!==0){x.hour=-1;} +if(!x.day&&x.day!==0){x.day=-1;} +if(!x.month&&x.month!==0){x.month=-1;} +if(!x.year&&x.year!==0){x.year=-1;} +if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());} +if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());} +if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());} +if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());} +if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());} +if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());} +if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());} +if(x.timezone){this.setTimezone(x.timezone);} +if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);} +return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;} +var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}} +return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();}; +Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;} +return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;} +if(!last&&q[1].length===0){last=true;} +if(!last){var qx=[];for(var j=0;j0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}} +if(rx[1].length1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];} +if(args){for(var i=0,px=args.shift();i2)?n:(n+(((n+2000)Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");} +var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});} +return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;} +for(var i=0;i\x3c/script>"):(D("safari")||D("konqueror"))&&g[y](S,10)),O[m](a)):P(g,"load",a)};K("google.setOnLoadCallback",google.T); +function P(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var e=a["on"+b];a["on"+b]=null!=e?aa([c,e]):c}}function aa(a){return function(){for(var b=0;b\x3c/script>'):"css"==a&&h.write('')}; +K("google.loader.writeLoadTag",google[z].d);google[z].Q=function(a){N=a};K("google.loader.rfm",google[z].Q);google[z].S=function(a){for(var b in a)"string"==typeof b&&b&&":"==b[q](0)&&!M[b]&&(M[b]=new T(b[A](1),a[b]))};K("google.loader.rpl",google[z].S);google[z].R=function(a){if((a=a.specs)&&a[w])for(var b=0;b + * Copyright: Copyright 2012-2013 UPMC Sorbonne Universités + * License: GPLv3 + */ + +(function($){ + + var SliceStat = Plugin.extend({ + + /** XXX to check + * @brief Plugin constructor + * @param options : an associative array of setting values + * @param element : + * @return : a jQuery collection of objects on which the plugin is + * applied, which allows to maintain chainability of calls + */ + init: function(options, element) { + // Call the parent constructor, see FAQ when forgotten + this._super(options, element); + + + /* Member variables */ + + /* Plugin events */ + + /* Setup query and record handlers */ + + // Explain this will allow query events to be handled + // What happens when we don't define some events ? + // Some can be less efficient + this.listen_query(options.query_uuid); + + /* GUI setup and event binding */ + // call function + + }, + + /* PLUGIN EVENTS */ + // on_show like in hazelnut + + + /* GUI EVENTS */ + + // a function to bind events here: click change + // how to raise manifold events + + + /* GUI MANIPULATION */ + + // We advise you to write function to change behaviour of the GUI + // Will use naming helpers to access content _inside_ the plugin + // always refer to these functions in the remaining of the code + + show_hide_button: function() + { + // this.id, this.el, this.cl, this.elts + // same output as a jquery selector with some guarantees + }, + + /* TEMPLATES */ + + // see in the html template + // How to load a template, use of mustache + + /* QUERY HANDLERS */ + + // How to make sure the plugin is not desynchronized + // He should manifest its interest in filters, fields or records + // functions triggered only if the proper listen is done + + // no prefix + + on_filter_added: function(filter) + { + + }, + + // ... be sure to list all events here + + /* RECORD HANDLERS */ + on_new_record: function(record) + { + console.log(record); + + $('iframe#slicestat_resource').attr('src','http://plestats.planet-lab.eu/node.php?node='+record.hostname); + + }, + + /* INTERNAL FUNCTIONS */ + _dummy: function() { + // only convention, not strictly enforced at the moment + }, + + }); + + /* Plugin registration */ + $.plugin('SliceStat', SliceStat); + + // TODO Here use cases for instanciating plugins in different ways like in the pastie. + +})(jQuery); diff --git a/plugins/slicestat/templates/slicestat.html b/plugins/slicestat/templates/slicestat.html new file mode 100644 index 00000000..c97cd9e0 --- /dev/null +++ b/plugins/slicestat/templates/slicestat.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/portal/contactview.py b/portal/contactview.py index 0f2e4010..c07f3977 100644 --- a/portal/contactview.py +++ b/portal/contactview.py @@ -40,6 +40,6 @@ class ContactView (View): def _display (self, request, form): return render(request, 'contact.html', { 'form': form, - 'topmenu_items': topmenu_items('Contact Us', request), + 'topmenu_items': topmenu_items('Contact', request), 'username': the_user (request) }) diff --git a/portal/homeview.py b/portal/homeview.py index b9d039a5..960c8f0d 100644 --- a/portal/homeview.py +++ b/portal/homeview.py @@ -14,8 +14,9 @@ class HomeView (View): # expose this so we can mention the backend URL on the welcome page def default_env (self): + config=Config() return { - 'MANIFOLD_URL':Config.manifold_url(), + 'MANIFOLD_URL':config.manifold_url(), } def post (self,request): @@ -56,7 +57,7 @@ class HomeView (View): def get (self, request, state=None): env = self.default_env() env['username']=the_user(request) - env['topmenu_items'] = topmenu_items('', request) + env['topmenu_items'] = topmenu_items(None, request) if state: env['state'] = state elif not env['username']: env['state'] = "Please sign in" return render_to_response('home-view.html',env, context_instance=RequestContext(request)) diff --git a/portal/resourceview.py b/portal/resourceview.py index 65b369a3..0ba8a26c 100644 --- a/portal/resourceview.py +++ b/portal/resourceview.py @@ -8,6 +8,7 @@ from ui.topmenu import topmenu_items, the_user from plugins.googlemap import GoogleMap from plugins.hazelnut import Hazelnut from plugins.lists.simplelist import SimpleList +from plugins.slicestat import SliceStat # View for 1 platform and its details class ResourceView(TemplateView): @@ -15,6 +16,8 @@ class ResourceView(TemplateView): def get_context_data(self, **kwargs): page = Page(self.request) + + page.add_js_files ( [ "js/common.functions.js" ] ) for key, value in kwargs.iteritems(): print "%s = %s" % (key, value) @@ -23,7 +26,7 @@ class ResourceView(TemplateView): resource_query = Query().get('resource')\ .filter_by('urn', '==', resource_urn)\ - .select('type','hrn','urn', 'latitude', 'longitude', 'country') + .select('hostname','type','hrn','urn', 'latitude', 'longitude', 'country') page.enqueue_query(resource_query) page.expose_js_metadata() @@ -63,16 +66,25 @@ class ResourceView(TemplateView): # query = resource_query, # ) + resource_stats = SliceStat( + title = None, + page = page, + stats = 'node', + key = 'hrn', + query = resource_query + ) + context = super(ResourceView, self).get_context_data(**kwargs) context['person'] = self.request.user context['resource'] = resourcelist.render(self.request) context['resource_as_map'] = resource_as_map.render(self.request) + context['resource_stats'] = resource_stats.render(self.request) # XXX This is repeated in all pages # more general variables expected in the template context['title'] = 'Information about a resource' # the menu items on the top - context['topmenu_items'] = topmenu_items('Dashboard', self.request) + context['topmenu_items'] = topmenu_items(None, self.request) # so we can sho who is logged context['username'] = the_user(self.request) diff --git a/portal/sliceview.py b/portal/sliceview.py index 4e69bc72..15a5e51a 100644 --- a/portal/sliceview.py +++ b/portal/sliceview.py @@ -38,7 +38,8 @@ class SliceView (LoginRequiredAutoLogoutView): page.add_js_files ( [ "js/common.functions.js" ] ) page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });') page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off")) - page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(Config.manifold_url())) + config=Config() + page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url())) page.expose_js_metadata() metadata = page.get_metadata() diff --git a/portal/templates/contact.html b/portal/templates/contact.html index 5161971b..26526477 100644 --- a/portal/templates/contact.html +++ b/portal/templates/contact.html @@ -22,9 +22,7 @@
{{ field.errors }} {{ field }}

{{ field.help_text }}

{% endfor %} -
- -
+ diff --git a/portal/templates/registration_view.html b/portal/templates/registration_view.html index d7788d0d..6f709f4f 100644 --- a/portal/templates/registration_view.html +++ b/portal/templates/registration_view.html @@ -91,9 +91,8 @@

Account Delegation: Manual (Advanced Users)

-
- -
+ +
diff --git a/portal/templates/resource.html b/portal/templates/resource.html index ed7beb08..5bdfdc9a 100644 --- a/portal/templates/resource.html +++ b/portal/templates/resource.html @@ -8,5 +8,6 @@

Resource

{{resource}} +{{resource_stats}} {{resource_as_map}} {% endblock %} diff --git a/portal/templates/slice-request-view.html b/portal/templates/slice-request-view.html index f437ae00..6aede04f 100644 --- a/portal/templates/slice-request-view.html +++ b/portal/templates/slice-request-view.html @@ -25,9 +25,7 @@

{{ field.help_text }}

{% endfor %} -
- -
+ diff --git a/setup.py b/setup.py index 98d1368e..157641a9 100644 --- a/setup.py +++ b/setup.py @@ -20,5 +20,5 @@ setup(packages = packages, ( 'static/img', glob ('static/img/*')), ( 'static/fonts', glob ('static/fonts/*')), ( 'templates', glob ('templates/*')), - ( 'apache', [ 'apache/myslice.conf', 'apache/myslice.wsgi' ]), + ( 'apache', [ 'apache/myslice.conf' ]), ]) diff --git a/ui/templates/widget-topmenu.html b/ui/templates/widget-topmenu.html index f5308de0..b31b1330 100644 --- a/ui/templates/widget-topmenu.html +++ b/ui/templates/widget-topmenu.html @@ -23,7 +23,7 @@ diff --git a/ui/topmenu.py b/ui/topmenu.py index 72904f9b..bdee674d 100644 --- a/ui/topmenu.py +++ b/ui/topmenu.py @@ -7,33 +7,35 @@ # ### a dropdown # { 'label': ..., 'href'=..., 'dropdown':True, 'contents': [ { 'label':.., 'href'} ] } # , ..] + +# current: the beginning of the label in the menu that you want to outline def topmenu_items (current,request=None): has_user=request.user.is_authenticated() result=[] if has_user: result.append({'label':'Dashboard', 'href': '/portal/dashboard/'}) result.append({'label':'Request a slice', 'href': '/portal/slice_request/'}) - result.append({'label':'My Account', 'href': '/portal/account/'}) - result.append({'label':'Contact Support', 'href': '/portal/contact/'}) -# Not really useful at this point, is it ? -# This should probably go into dashboard at some point -# result.append({'label':'Platforms', 'href': '/portal/platforms/'}) -# the code for building a dropdown instead - but somehow this is broken -# dropdown = [ {'label':'..', 'href': '..'}, ...] -# result.append({'label': 'More', 'href':"#", 'dropdown':True, 'contents':dropdown}) + dropdown = [] + dropdown.append({'label':'My Account', 'href': '/portal/account/'}) + dropdown.append({'label':'Contact Support', 'href': '/portal/contact/'}) + result.append({'label': 'More', 'href':"#", 'dropdown':True, 'contents':dropdown}) else: result.append({'label':'Home', 'href': '/login'}) # looks like this is accessible to non-logged users result.append({'label':'Platforms', 'href': '/portal/platforms/'}) result.append({'label':'Register', 'href': '/portal/register/'}) result.append({'label':'Contact Support', 'href': '/portal/contact/'}) - # mark active - for d in result: - if 'dropdown' in d: - for dd in d['contents']: - if dd['label'] == current: dd['is_active']=True - else: - if d['label'] == current: d['is_active']=True + # 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) + def mark_active(d): + if d['label'][:curlen].lower() == current: d['is_active']=True + for d in result: + mark_active(d) + if 'dropdown' in d: + for dd in d['contents']: mark_active(dd) return result def the_user (request): diff --git a/unfold/loginrequired.py b/unfold/loginrequired.py index 0f46ff79..ebe33d51 100644 --- a/unfold/loginrequired.py +++ b/unfold/loginrequired.py @@ -32,7 +32,9 @@ def logout_on_manifold_exception (fun_that_returns_httpresponse): except ManifoldException, manifold_result: # xxx we need a means to display this message to user... from django.contrib.auth import logout - logout(request) + # in some unusual cases, this might fail + try: logout(request) + except: pass return HttpResponseRedirect ('/') except Exception, e: # xxx we need to sugarcoat this error message in some error template... diff --git a/unfold/page.py b/unfold/page.py index 52d58770..5922ae7e 100644 --- a/unfold/page.py +++ b/unfold/page.py @@ -141,7 +141,8 @@ class Page: self.add_js_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";") def expose_js_manifold_config (self): - self.add_js_chunks(Config.manifold_js_export()) + config=Config() + self.add_js_chunks(config.manifold_js_export()) #################### requirements/prelude management # just forward to self.prelude - see decorator above