Merge branch 'master' of git://git.planet-lab.org/plstackapi
diff --git a/planetstack/core/xoslib/dashboards/gentle.html b/planetstack/core/xoslib/dashboards/gentle.html
index 707f10e..47386e8 100644
--- a/planetstack/core/xoslib/dashboards/gentle.html
+++ b/planetstack/core/xoslib/dashboards/gentle.html
@@ -19,6 +19,7 @@
 <script src="{{ STATIC_URL }}/js/vendor/backbone.wreqr.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/gentle.js"></script>
 
diff --git a/planetstack/core/xoslib/dashboards/helloworld.html b/planetstack/core/xoslib/dashboards/helloworld.html
index 9b61487..48badb6 100644
--- a/planetstack/core/xoslib/dashboards/helloworld.html
+++ b/planetstack/core/xoslib/dashboards/helloworld.html
@@ -8,6 +8,7 @@
 
 <script src="{{ STATIC_URL }}/js/vendor/underscore-min.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/backbone.js"></script>
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 
 <script src="{{ STATIC_URL }}/js/helloworld.js"></script>
diff --git a/planetstack/core/xoslib/dashboards/sliceEditor.html b/planetstack/core/xoslib/dashboards/sliceEditor.html
index bc3fa1b..c68f66b 100644
--- a/planetstack/core/xoslib/dashboards/sliceEditor.html
+++ b/planetstack/core/xoslib/dashboards/sliceEditor.html
@@ -7,6 +7,7 @@
 
 <link rel="stylesheet" type="text/css" href="{% static 'css/sliceEditor.css' %}" media="all">
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/sliceEditor.js"></script>
 
diff --git a/planetstack/core/xoslib/dashboards/sliverListTest.html b/planetstack/core/xoslib/dashboards/sliverListTest.html
index 255cbad..3093899 100644
--- a/planetstack/core/xoslib/dashboards/sliverListTest.html
+++ b/planetstack/core/xoslib/dashboards/sliverListTest.html
@@ -5,6 +5,7 @@
 <script src="{{ STATIC_URL }}/js/vendor/backbone-min.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/ICanHaz.min.js"></script>
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/sliverListTest.js"></script>
 
diff --git a/planetstack/core/xoslib/dashboards/test.html b/planetstack/core/xoslib/dashboards/test.html
index ca60567..48fbc65 100644
--- a/planetstack/core/xoslib/dashboards/test.html
+++ b/planetstack/core/xoslib/dashboards/test.html
@@ -7,6 +7,7 @@
 
 <link rel="stylesheet" type="text/css" href="{% static 'css/test.css' %}" media="all" >
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xosHelper.js"></script>
 <script src="{{ STATIC_URL }}/js/test.js"></script>
diff --git a/planetstack/core/xoslib/dashboards/xosAdminDashboard.html b/planetstack/core/xoslib/dashboards/xosAdminDashboard.html
index 8b64877..d8e083a 100644
--- a/planetstack/core/xoslib/dashboards/xosAdminDashboard.html
+++ b/planetstack/core/xoslib/dashboards/xosAdminDashboard.html
@@ -8,6 +8,7 @@
 <link rel="stylesheet" type="text/css" href="{% static 'css/xosAdminDashboard.css' %}" media="all" >
 <link rel="stylesheet" type="text/css" href="{% static 'css/xosAdminSite.css' %}" media="all" >
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xosHelper.js"></script>
 <script src="{{ STATIC_URL }}/js/xosAdminSite.js"></script>
diff --git a/planetstack/core/xoslib/dashboards/xosAdminWholePage.html b/planetstack/core/xoslib/dashboards/xosAdminWholePage.html
index 30f3509..ddcd683 100644
--- a/planetstack/core/xoslib/dashboards/xosAdminWholePage.html
+++ b/planetstack/core/xoslib/dashboards/xosAdminWholePage.html
@@ -8,6 +8,7 @@
 <link rel="stylesheet" type="text/css" href="{% static 'css/xosAdminWholePage.css' %}" media="all" >
 <link rel="stylesheet" type="text/css" href="{% static 'css/xosAdminSite.css' %}" media="all" >
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xosHelper.js"></script>
 <script src="{{ STATIC_URL }}/js/xosAdminSite.js"></script>
diff --git a/planetstack/core/xoslib/dashboards/xosDeveloper.html b/planetstack/core/xoslib/dashboards/xosDeveloper.html
index 58f2d08..95d1383 100644
--- a/planetstack/core/xoslib/dashboards/xosDeveloper.html
+++ b/planetstack/core/xoslib/dashboards/xosDeveloper.html
@@ -4,6 +4,7 @@
 <script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/xosDeveloper.js"></script>
 
diff --git a/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html b/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html
index d40409a..fad3217 100644
--- a/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html
+++ b/planetstack/core/xoslib/dashboards/xosDeveloper_datatables.html
@@ -4,6 +4,7 @@
 <script src="{{ STATIC_URL }}/js/vendor/backbone.babysitter.js"></script>
 <script src="{{ STATIC_URL }}/js/vendor/backbone.marionette.js"></script>
 
+<script src="{{ STATIC_URL }}/js/xoslib/xos-defaults.js"></script>
 <script src="{{ STATIC_URL }}/js/xoslib/xos-backbone.js"></script>
 <script src="{{ STATIC_URL }}/js/xosDeveloper_datatables.js"></script>
 
diff --git a/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js b/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
index 555d827..b514ff3 100644
--- a/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
+++ b/planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
@@ -29,7 +29,12 @@
                     var url = this.attributes.resource_uri;
 
                     if (!url) {
-                        url = this.urlRoot + this.id;
+                        if (this.id) {
+                            url = this.urlRoot + this.id;
+                        } else {
+                            // this happens when creating a new model.
+                            url = this.urlRoot;
+                        }
                     }
 
                     if (!url) {
@@ -253,14 +258,17 @@
                                                        modelName: "userDeployment"});
         this.userDeployments = new this.userDeploymentCollection();
 
-        this.deployment = XOSModel.extend({ urlRoot: DEPLOYMENT_API, modelName: "deployment" });
+        this.deployment = XOSModel.extend({ urlRoot: DEPLOYMENT_API,
+                                            modelName: "deployment",
+                                            defaults: xosdefaults.deployment });
         this.deploymentCollection = XOSCollection.extend({ urlRoot: DEPLOYMENT_API,
                                                            relatedCollections: {"nodes": "deployment", "slivers": "deploymentNetwork", "networkDeployments": "deployment", "userDeployments": "deployment"},
                                                            model: this.deployment,
                                                            modelName: "deployment"});
         this.deployments = new this.deploymentCollection();
 
-        this.image = XOSModel.extend({ urlRoot: IMAGE_API, modelName: "image" });
+        this.image = XOSModel.extend({ urlRoot: IMAGE_API,
+                                       modelName: "image" });
         this.imageCollection = XOSCollection.extend({ urlRoot: IMAGE_API,
                                                            model: this.image,
                                                            modelName: "image"});
diff --git a/planetstack/core/xoslib/static/js/xoslib/xos-defaults.js b/planetstack/core/xoslib/static/js/xoslib/xos-defaults.js
new file mode 100644
index 0000000..314d3be
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/xoslib/xos-defaults.js
@@ -0,0 +1,52 @@
+function xos_get_defaults() {
+  this.account = {"updated": null, "created": null, "deleted": false, "site": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.charge = {"updated": null, "slice": null, "created": null, "deleted": false, "object": null, "account": null, "date": null, "amount": 0.0, "state": "pending", "invoice": null, "coreHours": 0.0, "backend_status": "Provisioning in progress", "kind": "besteffort", "enacted": null};
+  this.dashboardView = {"updated": null, "name": "", "created": null, "deleted": false, "url": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.deployment = {"accessControl": "allow all", "updated": null, "admin_user": null, "name": "", "created": null, "deleted": false, "availability_zone": null, "backend_type": "", "auth_url": null, "admin_password": null, "backend_status": "Provisioning in progress", "admin_tenant": null, "enacted": null};
+  this.deploymentPrivilege = {"updated": null, "created": null, "deleted": false, "role": null, "user": null, "deployment": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.deploymentRole = {"updated": null, "created": null, "deleted": false, "role": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.flavor = {"updated": null, "description": null, "created": null, "deleted": false, "enacted": null, "default": false, "flavor": "", "backend_status": "Provisioning in progress", "order": 0, "name": ""};
+  this.image = {"updated": null, "name": "", "created": null, "deleted": false, "container_format": "", "disk_format": "", "path": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.imageDeployments = {"updated": null, "created": null, "deleted": false, "image": null, "deployment": null, "backend_status": "Provisioning in progress", "glance_image_id": null, "enacted": null};
+  this.invoice = {"updated": null, "created": null, "deleted": false, "account": null, "date": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.network = {"router_id": null, "subnet": "", "updated": null, "name": "", "created": null, "subnet_id": null, "network_id": null, "labels": null, "guaranteedBandwidth": 0, "deleted": false, "template": null, "owner": null, "backend_status": "Provisioning in progress", "ports": null, "permitAllSlices": false, "enacted": null};
+  this.networkDeployments = {"router_id": null, "subnet": "", "updated": null, "network": null, "created": null, "deleted": false, "subnet_id": null, "deployment": null, "backend_status": "Provisioning in progress", "net_id": null, "enacted": null};
+  this.networkParameter = {"updated": null, "created": null, "deleted": false, "object_id": null, "value": "", "content_type": null, "backend_status": "Provisioning in progress", "parameter": null, "enacted": null};
+  this.networkParameterType = {"updated": null, "description": "", "created": null, "deleted": false, "enacted": null, "backend_status": "Provisioning in progress", "name": ""};
+  this.networkSlice = {"updated": null, "slice": null, "network": null, "created": null, "deleted": false, "backend_status": "Provisioning in progress", "enacted": null};
+  this.networkSliver = {"updated": null, "network": null, "created": null, "deleted": false, "ip": null, "enacted": null, "backend_status": "Provisioning in progress", "port_id": null, "sliver": null};
+  this.networkTemplate = {"enacted": null, "updated": null, "backend_status": "Provisioning in progress", "description": null, "created": null, "deleted": false, "sharedNetworkName": null, "guaranteedBandwidth": 0, "visibility": "private", "translation": "none", "sharedNetworkId": null, "name": ""};
+  this.node = {"updated": null, "name": "", "created": null, "deleted": false, "site": null, "deployment": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.payment = {"updated": null, "created": null, "deleted": false, "account": null, "amount": 0.0, "date": "2014-11-12T01:19:50.077Z", "backend_status": "Provisioning in progress", "enacted": null};
+  this.planetStack = {"updated": null, "description": "PlanetStack", "created": null, "deleted": false, "backend_status": "Provisioning in progress", "enacted": null};
+  this.planetStackPrivilege = {"updated": null, "created": null, "deleted": false, "role": null, "user": null, "backend_status": "Provisioning in progress", "planetstack": 1, "enacted": null};
+  this.planetStackRole = {"updated": null, "created": null, "deleted": false, "role": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.project = {"updated": null, "name": "", "created": null, "deleted": false, "backend_status": "Provisioning in progress", "enacted": null};
+  this.reservation = {"updated": null, "slice": null, "created": null, "deleted": false, "startTime": null, "duration": 1, "backend_status": "Provisioning in progress", "enacted": null};
+  this.reservedResource = {"updated": null, "reservationSet": null, "created": null, "deleted": false, "resource": null, "enacted": null, "backend_status": "Provisioning in progress", "quantity": 1, "sliver": null};
+  this.role = {"updated": null, "description": "", "created": null, "deleted": false, "role": null, "content_type": null, "backend_status": "Provisioning in progress", "role_type": "", "enacted": null};
+  this.router = {"updated": null, "name": "", "created": null, "deleted": false, "owner": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.service = {"updated": null, "description": null, "created": null, "deleted": false, "enabled": true, "versionNumber": "", "published": true, "enacted": null, "backend_status": "Provisioning in progress", "name": ""};
+  this.serviceAttribute = {"updated": null, "name": "", "service": null, "created": null, "deleted": false, "value": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.serviceClass = {"updated": null, "membershipFee": 0, "membershipFeeMonths": 12, "created": null, "deleted": false, "description": "", "commitment": 365, "enacted": null, "backend_status": "Provisioning in progress", "upgradeRequiresApproval": false, "name": ""};
+  this.serviceResource = {"updated": null, "name": "", "bucketMaxSize": 0, "created": null, "deleted": false, "serviceClass": null, "maxUnitsDeployment": 1, "maxDuration": 1, "maxUnitsNode": 1, "cost": 0, "enacted": null, "backend_status": "Provisioning in progress", "bucketInRate": 0, "calendarReservable": true};
+  this.site = {"updated": null, "name": "", "created": null, "deleted": false, "enabled": true, "longitude": null, "site_url": null, "login_base": "", "location": "0,0", "latitude": null, "is_public": true, "backend_status": "Provisioning in progress", "abbreviated_name": "", "enacted": null};
+  this.siteCredential = {"updated": null, "name": "", "created": null, "deleted": false, "site": null, "key_id": "", "enacted": null, "backend_status": "Provisioning in progress", "enc_value": ""};
+  this.siteDeployments = {"updated": null, "created": null, "deleted": false, "tenant_id": null, "site": null, "deployment": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.sitePrivilege = {"updated": null, "created": null, "deleted": false, "site": null, "role": null, "user": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.siteRole = {"updated": null, "created": null, "deleted": false, "role": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.slice = {"updated": null, "imagePreference": "Ubuntu 12.04 LTS", "name": "", "service": null, "created": null, "deleted": false, "slice_url": "", "serviceClass": 1, "enabled": true, "site": null, "omf_friendly": false, "network": "Private Only", "max_slivers": 10, "mountDataSets": "GenBank", "enacted": null, "backend_status": "Provisioning in progress", "creator": null, "description": ""};
+  this.sliceCredential = {"updated": null, "slice": null, "name": "", "created": null, "deleted": false, "key_id": "", "enacted": null, "backend_status": "Provisioning in progress", "enc_value": ""};
+  this.sliceDeployments = {"router_id": null, "updated": null, "slice": null, "network_id": null, "created": null, "deleted": false, "tenant_id": null, "subnet_id": null, "deployment": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.slicePrivilege = {"updated": null, "slice": null, "created": null, "deleted": false, "role": null, "user": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.sliceRole = {"updated": null, "created": null, "deleted": false, "role": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.sliceTag = {"updated": null, "slice": null, "name": "", "created": null, "deleted": false, "value": "", "backend_status": "Provisioning in progress", "enacted": null};
+  this.sliver = {"node": null, "instance_id": null, "updated": null, "slice": null, "deploymentNetwork": null, "name": "", "created": null, "deleted": false, "ip": null, "image": null, "creator": null, "numberCores": 0, "instance_name": null, "userData": null, "backend_status": "Provisioning in progress", "flavor": 2, "enacted": null};
+  this.tag = {"updated": null, "name": "", "service": null, "created": null, "deleted": false, "value": "", "object_id": null, "content_type": null, "backend_status": "Provisioning in progress", "enacted": null};
+  this.usableObject = {"updated": null, "name": "", "created": null, "deleted": false, "backend_status": "Provisioning in progress", "enacted": null};
+  this.user = {"username": "Something", "public_key": null, "updated": null, "password": "", "is_readonly": false, "firstname": "", "user_url": null, "deleted": false, "lastname": "", "created": null, "is_active": true, "site": null, "phone": null, "is_staff": true, "last_login": "2014-11-12T01:19:50.111Z", "is_admin": true, "timezone": "America/New_York", "backend_status": "Provisioning in progress", "email": "", "enacted": null};
+  this.userCredential = {"updated": null, "name": "", "created": null, "deleted": false, "user": null, "key_id": "", "enacted": null, "backend_status": "Provisioning in progress", "enc_value": ""};
+  this.userDashboardView = {"updated": null, "created": null, "deleted": false, "dashboardView": null, "user": null, "backend_status": "Provisioning in progress", "order": 0, "enacted": null};
+  this.userDeployments = {"updated": null, "created": null, "deleted": false, "kuser_id": null, "user": null, "deployment": null, "backend_status": "Provisioning in progress", "enacted": null};
+};
+xosdefaults = new xos_get_defaults();
diff --git a/planetstack/core/xoslib/static/js/xoslib/xosHelper.js b/planetstack/core/xoslib/static/js/xoslib/xosHelper.js
index 11d97d6..0fc9496 100644
--- a/planetstack/core/xoslib/static/js/xoslib/xosHelper.js
+++ b/planetstack/core/xoslib/static/js/xoslib/xosHelper.js
@@ -126,9 +126,12 @@
     addShower: function(detailName, collection_name, regionName, title) {

         var app=this;

         return function() {

+            model = new xos[collection_name].model();

             detailViewClass = app[detailName];

-            detailView = new detailViewClass();

+            detailView = new detailViewClass({model: model});

             app[regionName].show(detailView);

+            $("#xos-detail-button-box").show();

+            $("#xos-listview-button-box").hide();

         }

     },

 

@@ -341,7 +344,7 @@
              addClicked: function(e) {
                 console.log("add");
                 e.preventDefault();
-                this.app.Router.navigate("add" + firstCharUpper(this.collection.modelName));
+                this.app.Router.navigate("add" + firstCharUpper(this.collection.modelName), {trigger: true});
              },
 

              initialize: function() {

diff --git a/planetstack/core/xoslib/tools/make_defaults.py b/planetstack/core/xoslib/tools/make_defaults.py
new file mode 100644
index 0000000..ad5377c
--- /dev/null
+++ b/planetstack/core/xoslib/tools/make_defaults.py
@@ -0,0 +1,41 @@
+import os
+import sys
+os.chdir("/opt/planetstack")
+sys.path.append("/opt/planetstack")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
+import django
+import core.models
+from django.db import models
+django.setup()

+from django.forms.models import model_to_dict
+import inspect
+from django.core import serializers
+import json
+
+print "function xos_get_defaults() {"
+
+for c in dir(core.models):
+    c = getattr(core.models,c)
+    if inspect.isclass(c) and issubclass(c, models.Model):
+        c=c()
+        classname = c.__class__.__name__
+        classname = classname[0].lower() + classname[1:]
+
+        if (classname in ["plCoreBase", "singletonModel"]):
+            continue
+
+        fieldNames = [f.name for f in c._meta.fields]
+
+        fields = json.loads(serializers.serialize("json",[c],fields=fieldNames))[0]["fields"]
+
+        for f in fields.keys():
+            if f in ['created', 'updated', 'enacted']:
+                fields[f] = None
+
+        fields_json = json.dumps(fields)
+
+        print "  this." + classname + " = " + fields_json + ";"
+
+print "};"
+print "xosdefaults = new xos_get_defaults();"
+