Merge branch 'master' into scheduler
authorJordan Augé <jordan.auge@lip6.fr>
Wed, 27 Nov 2013 08:32:58 +0000 (09:32 +0100)
committerJordan Augé <jordan.auge@lip6.fr>
Wed, 27 Nov 2013 08:32:58 +0000 (09:32 +0100)
28 files changed:
.gitignore
Makefile
apache/myslice.conf
debian/control
debian/myslice.install
debian/rules
debian/unfold.install
manifold/manifoldapi.py
manifold/manifoldproxy.py
manifold/metadata.py
myslice/config.py
myslice/settings.py
myslice/urls.py
myslice/wsgi.py
plugins/googlemap/__init__.py
plugins/querytable/static/js/querytable.js
plugins/senslabmap/__init__.py
plugins/senslabmap/static/css/map.css [deleted file]
plugins/senslabmap/static/css/senslabmap.css
plugins/senslabmap/static/js/map.js
plugins/senslabmap/static/js/senslabmap.js
plugins/senslabmap/templates/senslabmap.html
portal/actions.py
portal/homeview.py
portal/registrationview.py
portal/resourceview.py
portal/sliceview.py
setup.py

index db80e62..ed36fe7 100644 (file)
@@ -1,7 +1,5 @@
 # any local dbfile
 *.sqlite3
-# here is a mode to 'record' the backend answers and replay them offline
-offline-*
 # the usual useless crap
 TAGS
 *.pyc
index 9f3a563..473e3d7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ install:
            --install-scripts=$(DESTDIR)/$(datadir)/unfold \
            --install-data=$(DESTDIR)/$(datadir)/unfold
 
-#################### third-party layout is managed as art of collectstatic
+#################### third-party layout is managed as part of collectstatic
 static: force
        ./manage.py collectstatic --noinput
 
@@ -59,7 +59,7 @@ debian.source: force
        rsync -a $(RPMTARBALL) $(DEBTARBALL)
 
 debian.package:
-       debuild -uc -us -b 
+       debuild --set-envvar PREFIX=/usr -uc -us -b
 
 debian.clean:
        $(MAKE) -f debian/rules clean
@@ -116,7 +116,7 @@ SSHCOMMAND:=ssh root@$(MYSLICEBOX)
 LOCAL_RSYNC_EXCLUDES   := --exclude '*.pyc'
 LOCAL_RSYNC_EXCLUDES   += --exclude '*.sqlite3' --exclude myslice.ini
 LOCAL_RSYNC_EXCLUDES   += --exclude static --exclude templates --exclude build
-LOCAL_RSYNC_EXCLUDES   += --exclude to-be-integrated --exclude third-party --exclude 'offline*'
+LOCAL_RSYNC_EXCLUDES   += --exclude to-be-integrated --exclude third-party 
 # usual excludes
 RSYNC_EXCLUDES         := --exclude .git --exclude '*~' --exclude TAGS --exclude .DS_Store $(LOCAL_RSYNC_EXCLUDES) 
 # make -n will propagate as rsync -n 
@@ -127,7 +127,7 @@ RSYNC                       := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES)
 #################### minimal convenience for pushing work-in-progress in an apache-based depl.
 # xxx until we come up with a packaging this is going to be a wild guess
 # on debian04 I have stuff in /usr/share/myslice and a symlink in /root/myslice
-INSTALLED_MAIN         =/usr/share/unfold
+INSTALLED_MAIN         =/usr/share/pyshared
 # this is for a debian box
 INSTALLED_APACHE       =/etc/apache2/sites-available/
 
@@ -149,7 +149,7 @@ ifeq (,$(MYSLICEBOX))
        @exit 1
 else
        +$(RSYNC) ./apache/myslice.conf $(SSHURL)/$(INSTALLED_APACHE)/
-       +$(RSYNC) ./apache/init-ssl.sh ./apache/init-ssl.py $(SSHURL)/$(bindir)/
+       +$(RSYNC) ./apache/unfold-init-ssl.sh $(SSHURL)/$(bindir)/
 endif
 
 restart:
index b36a75e..c994af3 100644 (file)
@@ -1,5 +1,7 @@
+# xxx it might be smarter to install wsgi.py in some other location 
+# so we don't have to hard-wire these paths here
 <VirtualHost *:80>
-        WSGIScriptAlias / /usr/share/unfold/myslice/wsgi.py
+        WSGIScriptAlias / /usr/lib/python2.7/dist-packages/myslice/wsgi.py
         <Directory /usr/share/unfold/myslice>
         <Files wsgi.py>
         Order deny,allow
@@ -21,7 +23,7 @@
 # this to be optional on that port
 
 <VirtualHost *:443>
-        WSGIScriptAlias / /usr/share/unfold/myslice/wsgi.py
+        WSGIScriptAlias / /usr/lib/python2.7/dist-packages/myslice/wsgi.py
         <Directory /usr/share/unfold/apache>
         <Files myslice.wsgi>
         Order deny,allow
index 207b30d..4a4eb05 100644 (file)
@@ -4,6 +4,7 @@ Section: misc
 Priority: optional
 Standards-Version: 3.9.2
 Build-Depends: devscripts, debhelper (>=7.0.50~), debconf, dpatch, python-setuptools, make, python-django
+X-Python-Version: >= 2.7
 
 Package: myslice
 Architecture: any
index 5c36f72..e0c711d 100644 (file)
@@ -1 +1 @@
-usr/share/unfold/portal
+usr/lib*/python*/dist-packages/portal
index b8796e6..62e2bb6 100755 (executable)
@@ -2,4 +2,4 @@
 # -*- makefile -*-
 
 %:
-       dh $@
+       dh $@ --with python2 --buildsystem=python_distutils
index 5329158..5bf0af9 100644 (file)
@@ -1,12 +1,12 @@
+usr/lib*/python*/dist-packages/auth
+usr/lib*/python*/dist-packages/insert_above
+usr/lib*/python*/dist-packages/manifold
+usr/lib*/python*/dist-packages/plugins
+usr/lib*/python*/dist-packages/unfold
+usr/lib*/python*/dist-packages/ui
+usr/lib*/python*/dist-packages/myslice
+usr/lib*/python*/dist-packages/sample
 usr/share/unfold/static
 usr/share/unfold/templates
-usr/share/unfold/auth
-usr/share/unfold/insert_above
-usr/share/unfold/manifold
-usr/share/unfold/plugins
-usr/share/unfold/unfold
-usr/share/unfold/ui
-usr/share/unfold/myslice
-usr/share/unfold/sample
 manage.py usr/share/unfold/
 apache/myslice.conf /etc/apache2/sites-available
index 1b97505..664bb32 100644 (file)
@@ -72,8 +72,8 @@ class ManifoldAPI:
                     print "====> ManifoldAPI.%s"%repr(),"url",self.url
                     # No password in the logs
                     logAuth = copy.copy(self.auth)
-                    if 'AuthString' in logAuth:
-                        logAuth['AuthString']="XXX"
+                    for obfuscate in ['Authring','session']: 
+                        if obfuscate in logAuth:  logAuth[obfuscate]="XXX"
                     print "=> auth",logAuth
                     print "=> args",args,"kwds",kwds
                 annotations = {
@@ -92,14 +92,14 @@ class ManifoldAPI:
 
             except Exception,error:
                 print "** MANIFOLD API ERROR **"
-                if "Connection refused" in error:
-                    raise ManifoldException ( ManifoldResult (code=ManifoldCode.SERVER_UNREACHABLE,
-                                                              output="%s answered %s"%(self.url,error)))
-                # otherwise
                 if debug: 
                     print "===== xmlrpc catch-all exception:",error
                     import traceback
                     traceback.print_exc(limit=3)
+                if "Connection refused" in error:
+                    raise ManifoldException ( ManifoldResult (code=ManifoldCode.SERVER_UNREACHABLE,
+                                                              output="%s answered %s"%(self.url,error)))
+                # otherwise
                 print "<==== ERROR On ManifoldAPI.%s"%repr()
                 raise ManifoldException ( ManifoldResult (code=ManifoldCode.SERVER_UNREACHABLE, output="%s"%error) )
 
index 05486cb..99e7b0a 100644 (file)
@@ -25,14 +25,6 @@ debug_spin=0
 debug_empty=False
 #debug_empty=True
 
-# Historically we had a feature for developing without an Internet connection
-# However this won't work anymore as the python layer itself does manifold calls
-# before javascript has a chance to do so.
-# Might still come in handy if you want the fastest possible (locally cached) feedback
-# beware that this is very rough though...
-work_offline=False
-#work_offline=True
-
 # this view is what the javascript talks to when it sends a query
 # see also
 # myslice/urls.py
@@ -59,7 +51,6 @@ with the query passed using POST"""
         manifold_query = Query()
         #manifold_query = ManifoldQuery()
         manifold_query.fill_from_POST(request.POST)
-        offline_filename="%s/../offline-%s-%s.json"%(os.path.dirname(__file__),manifold_query.action,manifold_query.object)
         # retrieve session for request
 
         # We allow some requests to use the ADMIN user account
@@ -74,19 +65,6 @@ with the query passed using POST"""
             json_answer=json.dumps({'code':0,'value':[]})
             print "By-passing : debug_empty & 'get' request : returning a fake empty list"
             return HttpResponse (json_answer, mimetype="application/json")
-        ### patch : return the latest one..
-        if work_offline:
-            # if that won't work then we'll try to update anyways
-            try:
-                with (file(offline_filename,"r")) as f:
-                    json_answer=f.read()
-                print "By-passing : using contents from %s"%offline_filename
-                return HttpResponse (json_answer, mimetype="application/json")
-            except:
-                import traceback
-                traceback.print_exc()
-                print "Could not run in offline mode, PROCEEDING"
-                pass
                 
         # actually forward
         manifold_api= ManifoldAPI(auth=manifold_api_session_auth)
@@ -102,10 +80,6 @@ with the query passed using POST"""
             result [ 'description' ] = [ ResultValue.to_html (x) for x in result['description'] ]
 
         json_answer=json.dumps(result)
-        # if in debug mode we save this so we can use offline mode later
-        if debug:
-            with (file(offline_filename,"w")) as f:
-                f.write(json_answer)
 
         # this is an artificial delay added for debugging purposes only
         if debug_spin>0:
index 08fdf61..f7a5968 100644 (file)
@@ -9,10 +9,6 @@ from django.contrib                     import messages
 debug=False
 debug=True
 
-# turn this on if you want to work offline
-work_offline=False
-#work_offline=True
-
 class MetaData:
 
     def __init__ (self, auth):
@@ -20,14 +16,6 @@ class MetaData:
         self.hash_by_object={}
 
     def fetch (self, request):
-        offline_filename="%s/../offline-metadata.json"%os.path.dirname(__file__)
-        if work_offline:
-            try:
-                with file(offline_metadata) as f:
-                    self.hash_by_object=json.loads(f.read())
-                return
-            except:
-                print "metadata.work_offline: failed to decode %s"%offline_filename
         manifold_api = ManifoldAPI(self.auth)
         fields = ['table', 'column.name', 'column.qualifier', 'column.type', 
                   'column.is_array', 'column.description', 'column.default', 'key', 'capability']
@@ -59,10 +47,6 @@ class MetaData:
 #            print "Failed to retrieve metadata",rows_result.error()
 #            rows=[]
         self.hash_by_object = dict ( [ (row['table'], row) for row in rows ] )
-        # save for next time we use offline mode
-        if debug and rows:
-            with file(offline_filename,'w') as f:
-                f.write(json.dumps(self.hash_by_object))
 
     def to_json(self):
         return json.dumps(self.hash_by_object)
index 04f4aaf..908b651 100644 (file)
@@ -33,6 +33,8 @@ class Config(object):
         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.add_section('googlemap')
+        parser.set ('googlemap','api_key', None)
         parser.read (os.path.join(ROOT,'myslice/myslice.ini'))
         self.config_parser=parser
 
@@ -43,6 +45,9 @@ class Config(object):
         return (self.config_parser.get('manifold','admin_user'),
                 self.config_parser.get('manifold','admin_password'))
 
+    def googlemap_api_key (self):
+        return self.config_parser.get('googlemap','api_key')
+
     # exporting these details to js
     def manifold_js_export (self):
         return "var MANIFOLD_URL = '%s';\n"%self.manifold_url();
index 4878c0d..4df98e2 100644 (file)
@@ -14,13 +14,22 @@ try:
     # move one step up
     ROOT=os.path.realpath(ROOT+'/..')
 except:
+    # something is badly wrong here
     ROOT=None
-    if DEBUG:
-        import traceback
-        traceback.print_exc()
+    import traceback
+    traceback.print_exc()
 
-if not ROOT:
-    raise Exception,"Cannot find ROOT for myslice"
+# find out DATAROOT, which is different from ROOT 
+# when deployed from a package
+# this code is run by collectstatic too, so we cannot
+# assume we have ./static present already
+DATAROOT="/usr/share/unfold"
+# if not there, then we assume it's from a devel tree
+if not os.path.isdir (os.path.join(DATAROOT,"static")):
+    DATAROOT=ROOT
+
+if not os.path.isdir(ROOT): raise Exception,"Cannot find ROOT %s for myslice"%ROOT
+if not os.path.isdir(DATAROOT): raise Exception,"Cannot find DATAROOT %s for myslice"%DATAROOT
 
 ####################
 ADMINS = (
@@ -40,7 +49,7 @@ EMAIL_USE_TLS = False
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': os.path.join(ROOT,'myslice.sqlite3'), # Or path to database file if using sqlite3.
+        'NAME': os.path.join(DATAROOT,'myslice.sqlite3'), # Or path to database file if using sqlite3.
         'USER': '',                      # Not used with sqlite3.
         'PASSWORD': '',                  # Not used with sqlite3.
         'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
@@ -84,7 +93,7 @@ MEDIA_URL = ''
 # Don't put anything in this directory yourself; store your static files
 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
 # Example: "/home/media/media.lawrence.com/static/"
-STATIC_ROOT = os.path.join(ROOT,'static')
+STATIC_ROOT = os.path.join(DATAROOT,'static')
 
 # URL prefix for static files.
 # Example: "http://media.lawrence.com/static/"
@@ -154,7 +163,7 @@ TEMPLATE_DIRS = (
     # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
     # Always use forward slashes, even on Windows.
     # Don't forget to use absolute paths, not relative paths.
-    os.path.join(ROOT,"templates"),
+    os.path.join(DATAROOT,"templates"),
 )
 
 INSTALLED_APPS = (
@@ -183,7 +192,7 @@ INSTALLED_APPS = (
     # 'django.contrib.admindocs',
     'portal',
     # temporary - not packaged
-    'trash',
+    'trash',
     'sample',
 # DEPRECATED #    'django.contrib.formtools',
 # DEPRECATED ##    'crispy_forms',
index 3210957..8ff01f9 100644 (file)
@@ -63,6 +63,6 @@ urlpatterns = patterns(
     #
     # various trash views - bound to go away 
     #
-    url(r'^trash/', include('trash.urls')),
+#    url(r'^trash/', include('trash.urls')),
 
 )
index 5bd9728..2fa8416 100644 (file)
@@ -1,10 +1,6 @@
 import os
 import sys
 
-path = '/usr/share/unfold'
-if path not in sys.path:
-    sys.path.append(path)
-
 os.environ['DJANGO_SETTINGS_MODULE'] = 'myslice.settings'
 
 import django.core.handlers.wsgi
index bce84f5..8ceaec6 100644 (file)
@@ -2,14 +2,17 @@ from unfold.plugin import Plugin
 
 class GoogleMap (Plugin):
 
-    # set checkboxes if a final column with checkboxes is desired
-    # pass columns as the initial set of columns
-    #   if None then this is taken from the query's fields
+    # expcted input are
+    # query :           query about the slice 
+    # query_all :       query about all resources
+    # googlemap_key :   mandatory googlemap API v3 key
     # latitude,longitude, zoom : the starting point
-    def __init__ (self, query, query_all = None, latitude=43., longitude=7., zoom=4, **settings):
+    # apparently at some point there has been support for a boolean 'checkboxes' input arg but seems dropped
+    def __init__ (self, query, query_all, googlemap_api_key=None, latitude=43., longitude=7., zoom=4, **settings):
         Plugin.__init__ (self, **settings)
         self.query=query
         self.query_all = query_all
+        self.googlemap_api_key=googlemap_api_key
         self.query_all_uuid = query_all.query_uuid if query_all else None
         self.latitude=latitude
         self.longitude=longitude
@@ -23,8 +26,12 @@ class GoogleMap (Plugin):
         return env
 
     def requirements (self):
+        googlemap_api_url = "https://maps.googleapis.com/maps/api/js?"
+        if self.googlemap_api_key: googlemap_api_url+="key=%s&"%self.googlemap_api_key
+        googlemap_api_url += "sensor=false"
         reqs = {
-            'js_files' : [ "https://maps.googleapis.com/maps/api/js?sensor=false", 
+            # let users configure their googlemap API key in production deployements
+            'js_files' : [ googlemap_api_url,
                            "/js/googlemap.js",
                            "/js/markerclusterer.js",
                             "js/manifold.js", "js/manifold-query.js", 
index 6a553bc..e0ac3fd 100644 (file)
 
         checkbox_html : function (key, value)
         {
+//         if (debug) messages.debug("checkbox_html, value="+value);
             var result="";
             // Prefix id with plugin_uuid
             result += "<input";
             result += " name='" + key + "'";
             result += " type='checkbox'";
             result += " autocomplete='off'";
-            result += " value='" + value + "'";
+           if (value === undefined) {
+               messages.warning("querytable.checkbox_html - undefined value");
+           } else {
+               result += " value='" + value + "'";
+           }
             result += "></input>";
             return result;
-        }, // checkbox
+        }, 
 
 
         new_record: function(record)
             }
 
 
+           if (key_value === undefined) {
+               messages.warning("querytable.set_checkbox has no value to figure which line to tick");
+               return;
+           }
             var checkbox_id = this.flat_id(this.id('checkbox', key_value));
             // function escape_id(myid) is defined in portal/static/js/common.functions.js
             checkbox_id = escape_id(checkbox_id);
-               // using dataTables's $ to search also in nodes that are not currently displayed
+            // using dataTables's $ to search also in nodes that are not currently displayed
             var element = this.table.$(checkbox_id);
-               if (debug) messages.debug("set_checkbox checked=" + checked + " id=" + checkbox_id + " matches=" + element.length);
+            if (debug) 
+                messages.debug("set_checkbox checked=" + checked
+                               + " id=" + checkbox_id + " matches=" + element.length);
             element.attr('checked', checked);
         },
 
         {
             if (this.received_all_query) {
                // if the 'all' query has been dealt with already we may turn on the checkbox
-               if (debug) messages.debug("turning on checkbox for record "+record[this.key]);
                 this.set_checkbox(record, true);
             } else {
                // otherwise we need to remember that and do it later on
index 92895d0..03b06a4 100644 (file)
@@ -24,7 +24,7 @@ class SensLabMap (Plugin):
                            "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/map.css",
+            'css_files': [ "css/senslabmap.css",
                            ],
             }
         return reqs
diff --git a/plugins/senslabmap/static/css/map.css b/plugins/senslabmap/static/css/map.css
deleted file mode 100644 (file)
index ac4b7e0..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-canvas {
-  border:1px gray solid;
-  background-color: #202020;
-  margin: 10px;
-}
\ No newline at end of file
index 86f3638..bda3f45 100644 (file)
@@ -1,40 +1,5 @@
-.senslabmap {
-  margin: 10px;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  line-height: 18px;
-  color: #333333;
-  background-color: #ffffff;
-}
-
-#div3d {
-  height: 500px;
+#maps-container canvas {
+  border:1px gray solid;
   background-color: #202020;
-  z-index:-1
-}
-
-#selectionbox {
-  text-align: center;
-  padding:2px
-}
-
-#infobox {
-  text-align: center
-}
-
-#node_alive {
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFRQAABUUBbA3bdwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFHSURBVDiNtdSxSkJxFMfx7znVtZS2wFdIaLHBpcUl4UYPkRQNCU7hQ0RTYiAk9RDRhRpqaXHIJbBXEJwErXuj/2lJK60ovP3G/+F8/mf6iZkxnnIgib4ubIKsmpAFsm+jlhgtsLuUezw/8i0c35VxcOsquabGCcjyxE+fYg9O2DlbH9x+CRZvZJ4weSjCHiA/Y++qGcckBvuneXsCmB1ONEoemFD6JTQ6SISSREkHlEcXbl+mfIOLP2KfZdhoFPqB7F4vLj1HL/dAehoQ6Mx5Mysahc6PAQNIR6HzVdRyMWAAiFpOzYgNNCOngmXiAgXLqCHtuEBD2ipCMy5QhKaak9hAc9JUL6EB0InB63gJDbSe73UFitNqAsV6vtdVgEahHwhUp8CqjUI/ANDho/MGFTNqwGRBfh8zo+a8QWWE/1sffsw0jf0KmsOTrB0wIw8AAAAASUVORK5CYII=');
-  
-}
-
-#node_down {
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFRQAABUUBbA3bdwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEqSURBVDiNtdSxSkJxFMfx7zkGtQgKgU8gJLRcBZcmxxu9hNCU0BQ9RLSJTT1GdEenFrn87xIY+AQXhCu41OA9DdZNNMLy3288f87n/5uOmBkbqdf3KZfPMGsCAWYBACIJkCDimM8fmEze1ldlAwyCE8zuETna/GklZi+InJMkT9+Dnc4Bs9ktcAHIj9gKC9xRqVwxHL4C7BVPWXaDSG9LqCgE9MiyHLj8athshpg9/hJbo+UU5yKxVuuQxeIZqO0EQkqpdKzkeegBA6iR56ECbQ/YZ9qKmT/QrK1AwxsIDQXGHsGxIjLyxomMFPAHwkhRjYDUA5aiGilxPEWkuzMn0iWOpwqAcxFm/T9jZn2ciwC0GFar18CA5QXZmgIGH7vLov93D1ezw8V+B8jhfgJI7kYcAAAAAElFTkSuQmCC');
-}
-
-#node_selected {
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFRQAABUUBbA3bdwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAE0SURBVDiNtdS/SoJxFMbx7zn0xyGhIfAGGhJaTHFpaTW6iISUSGqKLiLaxChq6CKid21pEcklsKEbEBqCGizhfRrMF9SiP+/bM57D+fzO8OOYJMZj9YdZUk8biBXwHCj30WlD2Ma4pTd/qd3F14nZcdBOWqu4nQNLEy+N5p5QW9ou3HwK2sV1ire5I7AdwL7BhhHomJmXfW2u9QCmolY/fQjUfghFC4HV6KdDYC/a0M5aJWRXv8TGaK2rUgiM09YCcAdkYoHQBZYdUykBDCCDqeTIiwlgg8iLjik50FR0RDYxUGQdo5MYaHQcWTMxUNZ0LEwOtLDpyAIGfyhuusgCVzX/iKkcmzOVVc0/OoAqhQCj/neMuiqFAMCj4vTzAagBTB7IryNQYzA7XPS/7uFIMcbFfgcJcoL5SKOsjQAAAABJRU5ErkJggg==');
-}
-
-#node_used {
-  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAZJJREFUOI2t1D1LQlEcx/Hf+R/NTMKsawldqRZ7JDBIhyAIpwu9A6egpmrsbUQQ1FDQJL2B4E49LC0OuUQPToUKehFTosy6x9OQF8qiQu93Ohw4n7P9WDQaxQ+53Kx70Uv9MwEaDg85JsIAcG9epfL1u1SlblxU5eMRgFrzQ9YMOtAxt+CK7wedobGffrLKvKVvTmuJZROv55/vuaqq1rlzmE9tLXpWd33c7/8NAwAv71MmO+aXKsLwl6VxAsD8Ag7xqc2YO75GIPYXZkUgNuKcjpREwVuRhv5xB8DFurSYO77+X6i5mDu+7mJdmgUqWufKQauYVcNQyMN6tF4eGGgX7OWBAQ/r0UghNdIuZqWQGqGgY9Q2MOgYjdAgD43bBQ7y0DjlRPraLjAn0teUMW+TdoEZ8zZJxXrWNrBYzybpSZb1ksgX2sVKIl94kmWdABT1l72ldsGGUSQAqMln/bia2G4VO64mtmvyWQc+jUNFGqcPouALOidn/zsQJoQ8qx7u3IvLDTTWxvY9/AY2anmx3wGj5aLJgOrlPgAAAABJRU5ErkJggg==');
-}
+  margin: 10px;
+}
\ No newline at end of file
index 0e8e140..4e184cd 100644 (file)
@@ -11,7 +11,7 @@ var Senslab = {
 
     if (info && info[2] == "iot-lab" && info[3] == "info") {
       node.arch = info[0].split("-")[0];
-      node.id = info[0].split("-")[1];
+      node.id = parseInt(info[0].split("-")[1]);
       node.site = info[1];
       node.normalized = true;
     }
@@ -21,11 +21,22 @@ var Senslab = {
   },
   createMaps: function($container, sites, nodes) {
     var maps = {};
+    var $menu = $("<ul id='sites-tabs' class='nav nav-tabs' data-tabs='sites-tabs'/>").appendTo($container);
+    var $maps = $("<div id='maps' class='tab-content' />").appendTo($container);
+    
     $.each(sites, function(i, site) {
-      var $div = $("<div />").appendTo($container);
-      maps[site] = new Senslab.Map($div);
+      var entry = $("<li><a href='#" + site + "' data-toggle='tab'>" + site + "</a></li>").appendTo($menu);
+      var $tab = $("<div class='tab-pane' id='" + site + "' />").appendTo($maps);
+      maps[site] = new Senslab.Map($tab);
       maps[site].addNodes(nodes[site]);
     });
+    
+    $menu.find("li").eq(0).addClass("active");
+    $maps.find("div").eq(0).addClass("active");
+
+    if (!sites.length) {
+      $container.text("No nodes to display.");
+    }
   }
 };
 
index 2945e0d..a306219 100644 (file)
@@ -22,7 +22,7 @@
     },
     
     on_all_new_record: function(node) {
-      Senslab.normalize(node, this.key);
+      Senslab.normalize(node);
       if (node.normalized) {
         var site = node.site;
         if ($.inArray(site, this.sites) == -1) {
index aa9a39f..aec72cc 100644 (file)
@@ -1,30 +1 @@
-<div id="maps-container" oncontextmenu="return false;"></div>
-<script>
-$(function() {
-  $.getJSON("nodes.json", function(all_nodes) {
-    var sites = [], maps = {}, nodes = {};
-
-    $.each(all_nodes, function(i, node) {
-      Senslab.normalize(node);
-      var site = node.site;
-      if (site) {
-        if ($.inArray(site, sites) == -1) {
-          sites.push(site);
-          nodes[site] = [];
-        }
-        nodes[site].push(node);
-      } else {
-        console.warn("Node " + node + " has no site");
-      }
-    });
-
-    $container = $('#maps-container');
-
-    $.each(sites, function(i, site) {
-      var $div = $("<div />").appendTo($container);
-      maps[site] = new Senslab.Map($div);
-      maps[site].addNodes(nodes[site]);
-    });
-  });
-});
-</script>
\ No newline at end of file
+<div id="maps-container" oncontextmenu="return false;"></div>
\ No newline at end of file
index 7289594..bdb752f 100644 (file)
@@ -1,6 +1,6 @@
 from django.http                 import HttpResponse
 from manifold.core.query         import Query
-from manifold.manifoldapi        import execute_query
+from manifold.manifoldapi        import execute_query,execute_admin_query
 from portal.models               import PendingUser, PendingSlice
 import json
 
@@ -54,7 +54,7 @@ def sfa_add_slice(request, slice_params):
 def manifold_add_user(request, user_params):
     # user_params: email, password e.g., user_params = {'email':'aa@aa.com','password':'demo'}
     query = Query.create('local:user').set(user_params).select('email')
-    results = execute_query(request, query)
+    results = execute_admin_query(request, query)
     if not results:
         raise Exception, "Failed creating manifold user: %s" % user_params['email']
     result, = results
@@ -73,11 +73,11 @@ def manifold_update_user(request, user_params):
 
 def manifold_add_account(request, account_params):
     query = Query.create('local:account').set(account_params).select(['user', 'platform'])
-    results = execute_query(request,query)
+    results = execute_admin_query(request,query)
     if not results:
         raise Exception, "Failed creating manifold account on platform %s for user: %s" % (account_params['platform'], account_params['user'])
     result, = results
-    return (result['user'], result['platform'])
+    return result['user_id']
 
 def manifold_update_account(request,account_params):
     # account_params: config
index 5b82221..a665677 100644 (file)
@@ -34,12 +34,12 @@ class HomeView (FreeAccessView):
         # . or None if the backend could be reached but the authentication failed
         auth_result = authenticate(token=token)
         # use one or two columns for the layout - not logged in users will see the login prompt
-        env['layout_1_or_2']="layout-unfold2.html" if not username else "layout-unfold1.html"
         # high-level errors, like connection refused or the like
         if isinstance (auth_result, ManifoldResult):
             manifoldresult = auth_result
             # let's use ManifoldResult.__repr__
             env['state']="%s"%manifoldresult
+            env['layout_1_or_2']="layout-unfold2.html"
             return render_to_response('home-view.html',env, context_instance=RequestContext(request))
         # user was authenticated at the backend
         elif auth_result is not None:
@@ -50,10 +50,12 @@ class HomeView (FreeAccessView):
                 return HttpResponseRedirect ('/login-ok')
             else:
                 env['state'] = "Your account is not active, please contact the site admin."
+                env['layout_1_or_2']="layout-unfold2.html"
                 return render_to_response('home-view.html',env, context_instance=RequestContext(request))
         # otherwise
         else:
             env['state'] = "Your username and/or password were incorrect."
+            env['layout_1_or_2']="layout-unfold2.html"
             return render_to_response('home-view.html',env, context_instance=RequestContext(request))
 
     # login-ok sets state="Welcome to MySlice" in urls.py
index 85935f2..b9f35ff 100644 (file)
@@ -15,7 +15,7 @@ from manifold.manifoldapi       import execute_admin_query
 from manifold.core.query        import Query
 
 from portal.models              import PendingUser
-from portal.actions             import authority_get_pi_emails 
+from portal.actions             import authority_get_pi_emails, manifold_add_user,manifold_add_account
 
 # since we inherit from FreeAccessView we cannot redefine 'dispatch'
 # so let's override 'get' and 'post' instead
@@ -37,13 +37,13 @@ class RegistrationView (FreeAccessView):
         #onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple').filter_by('disabled', '==', 'False')
         #onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
         #if onelab_enabled:
-        if True:
-            print "ONELAB ENABLED"
-            authorities_query = Query.get('ple:authority').select('name', 'authority_hrn').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple', 'ple.nitos'])
-        else:
-            print "FIREXP ENABLED"
+        #if True:
+        #    print "ONELAB ENABLED"
+        #    authorities_query = Query.get('ple:authority').select('name', 'authority_hrn').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple', 'ple.nitos'])
+        #else:
+        #    print "FIREXP ENABLED"
 
-        authorities = execute_admin_query(request, authorities_query)
+        #authorities = execute_admin_query(request, authorities_query)
         # xxx tocheck - if authorities is empty, it's no use anyway
         # (users won't be able to validate the form anyway)
 
@@ -94,6 +94,7 @@ class RegistrationView (FreeAccessView):
 #                public_key = "ssh-rsa " + public_key
                 # Saving to DB
                 keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}'
+                auth_type = 'managed'
                 #keypair = re.sub("\r", "", keypair)
                 #keypair = re.sub("\n", "\\n", keypair)
                 #keypair = keypair.rstrip('\r\n')
@@ -109,6 +110,7 @@ class RegistrationView (FreeAccessView):
                     keypair = re.sub("\r", "", keypair)
                     keypair = re.sub("\n", "\\n",keypair)
                     keypair = ''.join(keypair.split())
+                    auth_type = 'user'
                     # for sending email
                     public_key = file_content
                 else:
@@ -117,6 +119,7 @@ class RegistrationView (FreeAccessView):
             #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
             #                email=reg_email, password=request.POST['password'], keypair=keypair)
             #b.save()
+            #saving to django db 'portal_pendinguser' table
             if not errors:
                 b = PendingUser(
                     first_name    = reg_fname, 
@@ -129,7 +132,10 @@ class RegistrationView (FreeAccessView):
                     keypair       = keypair,
                 )
                 b.save()
-
+                #saving to manifold
+                config = '{"firstname":'+ reg_fname + ', "lastname":'+ reg_lname + ', "authority":"'+ reg_auth + '"}'
+                user_params = {'email': reg_email, 'password': request.POST['password'], 'config': config}
+                manifold_add_user(request,user_params) 
                 # Send email
                 ctx = {
                     'first_name'    : reg_fname, 
@@ -148,7 +154,20 @@ class RegistrationView (FreeAccessView):
                 msg = render_to_string('user_request_email.txt', ctx)
                 send_mail("Onelab New User request for %s submitted"%reg_email, msg, reg_email, recipients)
 
-                return render(request, 'user_register_complete.html')
+                #return render(request, 'user_register_complete.html')
+            
+            #creating local:account in manifold
+            user_query  = Query().get('local:user').select('user_id','email')
+            user_details = execute_admin_query(self.request, user_query)
+            
+            for user_detail in user_details:
+                if user_detail['email']==reg_email:
+                    user_id = user_detail['user_id']
+                    #print "test"
+                    #print user_id
+            user_params = {'platform_id': 5, 'user_id': user_id, 'auth_type': auth_type, 'config': keypair}    
+            manifold_add_account(request,user_params)
+            return render(request, 'user_register_complete.html') 
 
         template_env = {
           'topmenu_items': topmenu_items('Register', request),
@@ -159,7 +178,7 @@ class RegistrationView (FreeAccessView):
           'authority_hrn': request.POST.get('authority_hrn', ''),
           'email': request.POST.get('email', ''),
           'password': request.POST.get('password', ''),           
-          'authorities': authorities,
+          #'authorities': authorities,
           }
         template_env.update(page.prelude_env ())
         return render(request, 'registration_view.html',template_env)
index f0f856a..155eff3 100644 (file)
@@ -1,13 +1,15 @@
-from manifold.core.query         import Query
-from unfold.page                 import Page
+from manifold.core.query        import Query
+from unfold.page                import Page
 
-from unfold.loginrequired        import FreeAccessView
-from ui.topmenu                  import topmenu_items, the_user
+from unfold.loginrequired       import FreeAccessView
+from ui.topmenu                 import topmenu_items, the_user
 
-from plugins.googlemap           import GoogleMap
-from plugins.querytable          import QueryTable
-from plugins.lists.simplelist    import SimpleList
-from plugins.slicestat           import SliceStat
+from plugins.googlemap          import GoogleMap
+from plugins.querytable         import QueryTable
+from plugins.lists.simplelist   import SimpleList
+from plugins.slicestat          import SliceStat
+
+from myslice.config             import Config
 
 # View for 1 platform and its details
 class ResourceView(FreeAccessView):
@@ -52,6 +54,7 @@ class ResourceView(FreeAccessView):
             togglable  = True,
             query      = resource_query,
             query_all  = resource_query,
+            googlemap_api_key = Config().googlemap_api_key(),
             checkboxes = False,
             # center on Paris
             #latitude   = 49.,
index 60415a4..006aa87 100644 (file)
@@ -157,6 +157,7 @@ class SliceView (LoginRequiredAutoLogoutView):
             togglable  = False,
             query      = sq_resource,
             query_all  = query_resource_all,
+            googlemap_api_key = Config().googlemap_api_key(),
             checkboxes = True,
             # center on Paris
             latitude   = 49.,
index e902e32..99b077d 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -13,12 +13,13 @@ from distutils.core import setup
 packages= [ os.path.dirname(init) for init in (glob("*/__init__.py")+glob("*/*/__init__.py")) ]
 
 setup(packages = packages,
+      # xxx somehow this does not seem to show up in debian packaging
       scripts = [ 'apache/unfold-init-ssl.sh' ],
       data_files = [ 
-        ( 'static/js', glob ('static/js/*')),
-        ( 'static/css', glob ('static/css/*')),
-        ( 'static/img', glob ('static/img/*')),
-        ( 'static/fonts', glob ('static/fonts/*')),
-        ( 'templates', glob ('templates/*')),
+        ( '/usr/share/unfold/static/js', glob ('static/js/*')),
+        ( '/usr/share/unfold/static/css', glob ('static/css/*')),
+        ( '/usr/share/unfold/static/img', glob ('static/img/*')),
+        ( '/usr/share/unfold/static/fonts', glob ('static/fonts/*')),
+        ( '/usr/share/unfold/templates', glob ('templates/*')),
         ( 'apache', [ 'apache/myslice.conf' ]),
         ])